From 8538a0445a06a8f3979aa374d690843b770ed661 Mon Sep 17 00:00:00 2001 From: Matthew Berry Date: Sun, 25 Oct 2020 14:07:00 -0700 Subject: [PATCH] properly handle rotating registers by an immediate, asr0=asr32 --- src/crab/arm/arm.cr | 22 ++++++++++++---------- src/crab/cpu.cr | 5 ++++- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/crab/arm/arm.cr b/src/crab/arm/arm.cr index 5f4b8c3..eba06d0 100644 --- a/src/crab/arm/arm.cr +++ b/src/crab/arm/arm.cr @@ -71,18 +71,20 @@ module ARM def rotate_register(instr : Word, set_conditions : Bool, allow_register_shifts = true) : Word reg = bits(instr, 0..3) shift_type = bits(instr, 5..6) - shift_amount = if allow_register_shifts && bit?(instr, 4) - shift_register = bits(instr, 8..11) - # todo weird logic if bottom byte of reg > 31 - @r[shift_register] & 0xFF - else - bits(instr, 7..11) - end + if allow_register_shifts && bit?(instr, 4) + shift_register = bits(instr, 8..11) + # todo weird logic if bottom byte of reg > 31 + shift_amount = @r[shift_register] & 0xFF + immediate = false + else + shift_amount = bits(instr, 7..11) + immediate = true + end case shift_type when 0b00 then lsl(@r[reg], shift_amount, set_conditions) - when 0b01 then lsr(@r[reg], shift_amount, false, set_conditions) - when 0b10 then asr(@r[reg], shift_amount, false, set_conditions) - when 0b11 then ror(@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, immediate, set_conditions) + when 0b11 then ror(@r[reg], shift_amount, immediate, set_conditions) else raise "Impossible shift type: #{hex_str shift_type}" end end diff --git a/src/crab/cpu.cr b/src/crab/cpu.cr index cbf89ab..4b234fa 100644 --- a/src/crab/cpu.cr +++ b/src/crab/cpu.cr @@ -171,7 +171,10 @@ class CPU # Arithmetic shift right def asr(word : Word, bits : Int, immediate : Bool, set_conditions : Bool) : Word 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 @cpsr.carry = bit?(word, bits - 1) if set_conditions word >> bits | (0xFFFFFFFF_u32 &* (word >> 31)) << (32 - bits)