properly handle rotating registers by an immediate, asr0=asr32

This commit is contained in:
Matthew Berry 2020-10-25 14:07:00 -07:00
parent bfc53e0222
commit 8538a0445a
2 changed files with 16 additions and 11 deletions

View file

@ -71,18 +71,20 @@ module ARM
def rotate_register(instr : Word, set_conditions : Bool, allow_register_shifts = true) : Word def rotate_register(instr : Word, set_conditions : Bool, allow_register_shifts = true) : Word
reg = bits(instr, 0..3) reg = bits(instr, 0..3)
shift_type = bits(instr, 5..6) shift_type = bits(instr, 5..6)
shift_amount = if allow_register_shifts && bit?(instr, 4) if allow_register_shifts && bit?(instr, 4)
shift_register = bits(instr, 8..11) shift_register = bits(instr, 8..11)
# todo weird logic if bottom byte of reg > 31 # todo weird logic if bottom byte of reg > 31
@r[shift_register] & 0xFF shift_amount = @r[shift_register] & 0xFF
else immediate = false
bits(instr, 7..11) else
end shift_amount = bits(instr, 7..11)
immediate = true
end
case shift_type case shift_type
when 0b00 then lsl(@r[reg], shift_amount, set_conditions) when 0b00 then lsl(@r[reg], shift_amount, set_conditions)
when 0b01 then lsr(@r[reg], shift_amount, false, set_conditions) when 0b01 then lsr(@r[reg], shift_amount, immediate, set_conditions)
when 0b10 then asr(@r[reg], shift_amount, false, set_conditions) when 0b10 then asr(@r[reg], shift_amount, immediate, set_conditions)
when 0b11 then ror(@r[reg], shift_amount, false, set_conditions) when 0b11 then ror(@r[reg], shift_amount, immediate, set_conditions)
else raise "Impossible shift type: #{hex_str shift_type}" else raise "Impossible shift type: #{hex_str shift_type}"
end end
end end

View file

@ -171,7 +171,10 @@ class CPU
# Arithmetic shift right # Arithmetic shift right
def asr(word : Word, bits : Int, immediate : Bool, set_conditions : Bool) : Word def asr(word : Word, bits : Int, immediate : Bool, set_conditions : Bool) : Word
log "asr - word:#{hex_str word}, bits:#{bits}" log "asr - word:#{hex_str word}, bits:#{bits}"
return word if bits == 0 if bits == 0
return word unless immediate
bits = 32
end
if bits <= 31 if bits <= 31
@cpsr.carry = bit?(word, bits - 1) if set_conditions @cpsr.carry = bit?(word, bits - 1) if set_conditions
word >> bits | (0xFFFFFFFF_u32 &* (word >> 31)) << (32 - bits) word >> bits | (0xFFFFFFFF_u32 &* (word >> 31)) << (32 - bits)