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