implement sbc, make data_processing use abstracted arith

This commit is contained in:
Matthew Berry 2020-10-13 18:59:40 -07:00
parent 86195d55d1
commit cbe206b13e
3 changed files with 18 additions and 5 deletions

View file

@ -17,9 +17,9 @@ module ARM
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] = add(@r[rn], operand_2, set_conditions)
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 0x5 then res = @r[rd] = adc(@r[rn], operand_2, set_conditions)
when 0x6 then res = @r[rd] = sbc(@r[rn], operand_2, set_conditions)
when 0x7 then res = @r[rd] = sbc(operand_2, @r[rn], set_conditions)
when 0x8 then res = @r[rn] & operand_2
when 0x9 then res = @r[rn] ^ operand_2
when 0xA then res = sub(@r[rn], operand_2, set_conditions)

View file

@ -125,6 +125,19 @@ class CPU
res
end
# Subtract two values with carry
def sbc(operand_1 : Word, operand_2 : Word, set_conditions) : Word
log "sbc - operand_1:#{hex_str operand_1}, operand_2:#{hex_str operand_2}"
res = operand_1 &- operand_2 &+ @cpsr.carry.to_unsafe &- 1
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
# Add two values
def add(operand_1 : Word, operand_2 : Word, set_conditions) : Word
log "add - operand_1:#{hex_str operand_1}, operand_2:#{hex_str operand_2}"

View file

@ -11,14 +11,14 @@ module THUMB
when 0b0011 then res = @r[rd] = lsr(@r[rd], @r[rs], true)
when 0b0100 then res = @r[rd] = asr(@r[rd], @r[rs], true)
when 0b0101 then res = @r[rd] = adc(@r[rd], @r[rs], true)
when 0b0110 then res = @r[rd] = @r[rd] &- @r[rs] &- ~@cpsr.carry.to_unsafe
when 0b0110 then res = @r[rd] = sbc(@r[rd], @r[rs], true)
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 = sub(@r[rd], @r[rs], true)
when 0b1011 then res = add(@r[rd], @r[rs], true)
when 0b1100 then res = @r[rd] = @r[rd] | @r[rs]
when 0b1101 then res = @r[rd] = @r[rs] * @r[rd]
when 0b1101 then res = @r[rd] = @r[rs] &* @r[rd]
when 0b1110 then res = @r[rd] = @r[rd] & ~@r[rs]
when 0b1111 then res = @r[rd] = ~@r[rs]
else raise "Invalid alu op: #{op}"