mirror of
https://github.com/mattrberry/crab.git
synced 2025-02-02 07:57:58 +01:00
set carry flag from barrel shifter ops (arm & thumb)
This commit is contained in:
parent
8e6040e4c4
commit
7d8e2dccef
5 changed files with 24 additions and 17 deletions
|
@ -68,7 +68,7 @@ module ARM
|
|||
puts "Unused instruction: #{hex_str instr}"
|
||||
end
|
||||
|
||||
def rotate_register(instr : Word, allow_register_shifts = true) : Word
|
||||
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)
|
||||
|
@ -79,10 +79,10 @@ module ARM
|
|||
bits(instr, 7..11)
|
||||
end
|
||||
case shift_type
|
||||
when 0b00 then lsl(@r[reg], shift_amount)
|
||||
when 0b01 then lsr(@r[reg], shift_amount)
|
||||
when 0b10 then asr(@r[reg], shift_amount)
|
||||
when 0b11 then ror(@r[reg], shift_amount)
|
||||
when 0b00 then lsl(@r[reg], shift_amount, set_conditions)
|
||||
when 0b01 then lsr(@r[reg], shift_amount, set_conditions)
|
||||
when 0b10 then asr(@r[reg], shift_amount, set_conditions)
|
||||
when 0b11 then ror(@r[reg], shift_amount, set_conditions)
|
||||
else raise "Impossible shift type: #{hex_str shift_type}"
|
||||
end
|
||||
end
|
||||
|
@ -90,6 +90,6 @@ module ARM
|
|||
def immediate_offset(instr : Word) : Word
|
||||
rotate = bits(instr, 8..11)
|
||||
imm = bits(instr, 0..7)
|
||||
ror(imm, 2 * rotate)
|
||||
ror(imm, 2 * rotate, false)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,12 +5,12 @@ module ARM
|
|||
set_conditions = bit?(instr, 20)
|
||||
rn = bits(instr, 16..19)
|
||||
rd = bits(instr, 12..15)
|
||||
# todo set carry flag from barrel shifter
|
||||
operand_2 = if imm_flag # Operand 2 is an immediate
|
||||
immediate_offset bits(instr, 0..11)
|
||||
else # Operand 2 is a register
|
||||
rotate_register bits(instr, 0..11)
|
||||
rotate_register bits(instr, 0..11), set_conditions
|
||||
end
|
||||
# todo handle carry flag on all ops
|
||||
case opcode
|
||||
when 0x0 then res = @r[rd] = @r[rn] & operand_2
|
||||
when 0x1 then res = @r[rd] = @r[rn] ^ operand_2
|
||||
|
|
|
@ -10,7 +10,7 @@ module ARM
|
|||
rn = bits(instr, 16..19)
|
||||
rd = bits(instr, 12..15)
|
||||
operand_2 = if imm_flag # Operand 2 is a register (opposite of data procesing for some reason)
|
||||
rotate_register bits(instr, 0..11), allow_register_shifts: false
|
||||
rotate_register bits(instr, 0..11), set_conditions: false, allow_register_shifts: false
|
||||
else # Operand 2 is an immediate offset
|
||||
immediate_offset bits(instr, 0..11)
|
||||
end
|
||||
|
|
|
@ -83,22 +83,30 @@ class CPU
|
|||
end
|
||||
|
||||
# Logical shift left
|
||||
def lsl(word : Word, bits : Int) : Word
|
||||
def lsl(word : Word, bits : Int, set_conditions : Bool) : Word
|
||||
log "lsl - word:#{hex_str word}, bits:#{bits}"
|
||||
@cpsr.carry = bit?(word, 32 - bits) if set_conditions
|
||||
word << bits
|
||||
end
|
||||
|
||||
# Logical shift right
|
||||
def lsr(word : Word, bits : Int) : Word
|
||||
def lsr(word : Word, bits : Int, set_conditions : Bool) : Word
|
||||
log "lsr - word:#{hex_str word}, bits:#{bits}"
|
||||
@cpsr.carry = bit?(word, bits - 1) if set_conditions
|
||||
word >> bits
|
||||
end
|
||||
|
||||
# Arithmetic shift right
|
||||
def asr(word : Word, bits : Int) : Word
|
||||
def asr(word : Word, bits : Int, set_conditions : Bool) : Word
|
||||
log "asr - word:#{hex_str word}, bits:#{bits}"
|
||||
@cpsr.carry = bit?(word, bits - 1) if set_conditions
|
||||
word // (2 ** bits)
|
||||
end
|
||||
|
||||
# Rotate right
|
||||
def ror(word : Word, bits : Int) : Word
|
||||
def ror(word : Word, bits : Int, set_conditions : Bool) : Word
|
||||
log "ror - word:#{hex_str word}, bits:#{bits}"
|
||||
@cpsr.carry = bit?(word, bits - 1) if set_conditions
|
||||
word >> bits | word << (32 - bits)
|
||||
end
|
||||
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
module THUMB
|
||||
def thumb_move_shifted_register(instr : Word) : Nil
|
||||
# todo carry flags (currently first divergence on armwrestler)
|
||||
op = bits(instr, 11..12)
|
||||
offset = bits(instr, 6..10)
|
||||
rs = bits(instr, 3..5)
|
||||
rd = bits(instr, 0..2)
|
||||
@r[rd] = case op
|
||||
when 0b00 then lsl(@r[rs], offset)
|
||||
when 0b01 then lsr(@r[rs], offset)
|
||||
when 0b10 then asr(@r[rs], offset)
|
||||
when 0b00 then lsl(@r[rs], offset, true)
|
||||
when 0b01 then lsr(@r[rs], offset, true)
|
||||
when 0b10 then asr(@r[rs], offset, true)
|
||||
else raise "Invalid shifted register op: #{op}"
|
||||
end
|
||||
@cpsr.zero = @r[rd] == 0
|
||||
|
|
Loading…
Add table
Reference in a new issue