abstract subtraction, set carry/overflow flags for subtraction

This commit is contained in:
Matthew Berry 2020-09-28 00:12:47 -07:00
parent 15433454a4
commit 116058472c
5 changed files with 21 additions and 7 deletions

View file

@ -14,15 +14,15 @@ module ARM
case opcode
when 0x0 then res = @r[rd] = @r[rn] & operand_2
when 0x1 then res = @r[rd] = @r[rn] ^ operand_2
when 0x2 then res = @r[rd] = @r[rn] &- operand_2
when 0x3 then res = @r[rd] = operand_2 &- @r[rn]
when 0x2 then res = @r[rd] = sub(@r[rn], operand_2, set_conditions)
when 0x3 then res = @r[rd] = sub(operand_2, @r[rn], set_conditions)
when 0x4 then res = @r[rd] = @r[rn] &+ operand_2
when 0x5 then res = @r[rd] = @r[rn] &+ operand_2 &+ @cpsr.carry.to_unsafe
when 0x6 then res = @r[rd] = @r[rn] &- operand_2 &+ @cpsr.carry.to_unsafe &- 1
when 0x7 then res = @r[rd] = operand_2 &- @r[rn] &+ @cpsr.carry.to_unsafe &- 1
when 0x8 then res = @r[rn] & operand_2
when 0x9 then res = @r[rn] ^ operand_2
when 0xA then res = @r[rn] &- operand_2
when 0xA then res = sub(@r[rn], operand_2, set_conditions)
when 0xB then res = @r[rn] &+ operand_2
when 0xC then res = @r[rd] = @r[rn] | operand_2
when 0xD then res = @r[rd] = operand_2

View file

@ -110,6 +110,19 @@ class CPU
word >> bits | word << (32 - bits)
end
# Subtract two values
def sub(operand_1 : Word, operand_2 : Word, set_conditions) : Word
log "sub - operand_1:#{hex_str operand_1}, operand_2:#{hex_str operand_2}"
res = operand_1 &- operand_2
if set_conditions
@cpsr.overflow = bit?((operand_1 ^ operand_2) & (operand_1 ^ res), 31)
@cpsr.carry = operand_1 >= operand_2
@cpsr.zero = res == 0
@cpsr.negative = bit?(res, 31)
end
res
end
def print_state(instr : Word) : Nil
{% if flag? :trace %}
@r.each do |reg|

View file

@ -11,7 +11,7 @@ module THUMB
@r[imm]
end
if sub
@r[rd] = @r[rs] &- operand
@r[rd] = sub(@r[rs], operand, true)
else
@r[rd] = @r[rs] &+ operand
end

View file

@ -3,6 +3,7 @@ module THUMB
op = bits(instr, 6..9)
rs = bits(instr, 3..5)
rd = bits(instr, 0..2)
# todo handle flags for all ops
case op
when 0b0000 then res = @r[rd] = @r[rd] & @r[rs]
when 0b0001 then res = @r[rd] = @r[rd] ^ @r[rs]
@ -14,7 +15,7 @@ module THUMB
when 0b0111 then res = @r[rd] = ror(@r[rd], @r[rs], true)
when 0b1000 then res = @r[rd] & @r[rs]
when 0b1001 then res = @r[rd] = (-@r[rs].to_i32!).to_u32!
when 0b1010 then res = @r[rd] &- @r[rs]
when 0b1010 then res = sub(@r[rd], @r[rs], true)
when 0b1011 then res = @r[rd] &+ @r[rs]
when 0b1100 then res = @r[rd] = @r[rd] | @r[rs]
when 0b1101 then res = @r[rd] = @r[rs] * @r[rd]

View file

@ -6,9 +6,9 @@ module THUMB
# todo handle carry flag on all ops
case op
when 0b00 then res = @r[rd] = offset
when 0b01 then res = @r[rd] &- offset
when 0b01 then res = sub(@r[rd], offset, true)
when 0b10 then res = @r[rd] &+= offset
when 0b11 then res = @r[rd] &-= offset
when 0b11 then res = @r[rd] = sub(@r[rd], offset, true)
else raise "Invalid move/compare/add/subtract op: #{op}"
end
@cpsr.zero = res == 0