mirror of
https://github.com/mattrberry/crab.git
synced 2025-01-19 10:26:44 +01:00
data processing logical flags, minor rotate_register patch, abstract immediate_offset
This commit is contained in:
parent
64c8b26fb8
commit
df79b7b48b
2 changed files with 30 additions and 22 deletions
|
@ -108,12 +108,12 @@ module ARM
|
|||
end
|
||||
|
||||
def rotate_register(instr : Word) : Word
|
||||
shift = bits(instr, 4..11)
|
||||
reg = bits(instr, 0..3)
|
||||
shift_type = bits(instr, 5..6)
|
||||
shift_amount = if bit?(instr, 4)
|
||||
shift_register = bits(instr, 8..11)
|
||||
@r[shift_register] & 0xF
|
||||
# todo weird logic if bottom byte of reg > 31
|
||||
@r[shift_register] & 0xFF
|
||||
else
|
||||
bits(instr, 7..11)
|
||||
end
|
||||
|
@ -125,4 +125,10 @@ module ARM
|
|||
else raise "Impossible shift type: #{hex_str shift_type}"
|
||||
end
|
||||
end
|
||||
|
||||
def immediate_offset(instr : Word) : Word
|
||||
rotate = bits(instr, 8..11)
|
||||
imm = bits(instr, 0..7)
|
||||
ror(imm, 2 * rotate)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,36 +1,38 @@
|
|||
module ARM
|
||||
def arm_data_processing(instr : Word) : Nil
|
||||
# todo all resulting flags
|
||||
imm_flag = bit?(instr, 25)
|
||||
opcode = bits(instr, 21..24)
|
||||
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
|
||||
rotate = bits(instr, 8..11)
|
||||
imm = bits(instr, 0..7)
|
||||
ror(imm, 2 * rotate)
|
||||
immediate_offset bits(instr, 0..11)
|
||||
else # Operand 2 is a register
|
||||
rotate_register bits(instr, 0..11)
|
||||
end
|
||||
case opcode
|
||||
when 0x0 then @r[rd] = rn & operand_2
|
||||
when 0x1 then @r[rd] = rn ^ operand_2
|
||||
when 0x2 then @r[rd] = rn &- operand_2
|
||||
when 0x3 then @r[rd] = operand_2 &- rn
|
||||
when 0x4 then @r[rd] = rn &+ operand_2
|
||||
when 0x5 then @r[rd] = rn &+ operand_2 &+ @cpsr.carry.to_unsafe
|
||||
when 0x6 then @r[rd] = rn &- operand_2 &+ @cpsr.carry.to_unsafe &- 1
|
||||
when 0x7 then @r[rd] = operand_2 &- rn &+ @cpsr.carry.to_unsafe &- 1
|
||||
when 0x8
|
||||
when 0x9
|
||||
when 0xA
|
||||
when 0xB
|
||||
when 0xC then @r[rd] = rn | operand_2
|
||||
when 0xD then @r[rd] = operand_2
|
||||
when 0xE then @r[rd] = rn & ~operand_2
|
||||
when 0xF then @r[rd] = ~operand_2
|
||||
when 0x0 then res = @r[rd] = rn & operand_2
|
||||
when 0x1 then res = @r[rd] = rn ^ operand_2
|
||||
when 0x2 then res = @r[rd] = rn &- operand_2
|
||||
when 0x3 then res = @r[rd] = operand_2 &- rn
|
||||
when 0x4 then res = @r[rd] = rn &+ operand_2
|
||||
when 0x5 then res = @r[rd] = rn &+ operand_2 &+ @cpsr.carry.to_unsafe
|
||||
when 0x6 then res = @r[rd] = rn &- operand_2 &+ @cpsr.carry.to_unsafe &- 1
|
||||
when 0x7 then res = @r[rd] = operand_2 &- rn &+ @cpsr.carry.to_unsafe &- 1
|
||||
when 0x8 then res = rn & operand_2
|
||||
when 0x9 then res = rn ^ operand_2
|
||||
when 0xA then res = rn &- operand_2
|
||||
when 0xB then res = rn &+ operand_2
|
||||
when 0xC then res = @r[rd] = rn | operand_2
|
||||
when 0xD then res = @r[rd] = operand_2
|
||||
when 0xE then res = @r[rd] = rn & ~operand_2
|
||||
when 0xF then res = @r[rd] = ~operand_2
|
||||
else raise "Unimplemented execution of data processing opcode: #{hex_str opcode}"
|
||||
end
|
||||
if set_conditions # todo this only works for logical ops, not arithmetic
|
||||
@cpsr.zero = res == 0
|
||||
@cpsr.negative = bit?(res, 31)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue