[CHANGED] Factored out opcode group #3 (MUL, IMUL, DIV, IDIV, NEG, and NOT)

This commit is contained in:
Sami Samhuri 2009-06-26 11:25:10 -07:00
parent 42c07eb18d
commit 448c47156e

View file

@ -13,7 +13,7 @@ module Assembler
include Registers include Registers
DEBUG_OUTPUT = true DEBUG_OUTPUT = false
# 0.size gives the real answer, we only do x86-32 though # 0.size gives the real answer, we only do x86-32 though
MachineBytes = 4 MachineBytes = 4
@ -233,6 +233,7 @@ module Assembler
rm = eff_addr.regnum rm = eff_addr.regnum
end end
# Bare displacements, e.g. [32] or [0x1234abcd]
elsif eff_addr.index? && eff_addr.index.is_a?(Numeric) elsif eff_addr.index? && eff_addr.index.is_a?(Numeric)
# disp8, mod == 01 # disp8, mod == 01
@ -249,13 +250,13 @@ module Assembler
raise "address must fit in 32 bits, this doesn't: #{eff_addr.index}" raise "address must fit in 32 bits, this doesn't: #{eff_addr.index}"
end end
# SIB
elsif eff_addr.index? elsif eff_addr.index?
# scale-index-base, mod == 00 and rm == 100 # scale-index-base, mod == 00 and rm == 100
rm = 4 rm = 4
sib = mk_sib(eff_addr.scale || 1, eff_addr.index, eff_addr.base) sib = mk_sib(eff_addr.scale || 1, eff_addr.index, eff_addr.base)
else else
# TODO support scale-index-base byte
raise "unsupported effective address: #{addr.inspect}" raise "unsupported effective address: #{addr.inspect}"
end end
@ -566,24 +567,12 @@ module Assembler
end end
# Signed multiply.
def imul(*ops) def imul(*ops)
case ops.size case ops.size
when 1 when 1
op = ops[0] group3(ops[0], 5, 'IMUL')
if rm?(op)
asm do
emit_byte(0xf7)
emit_modrm(op, 5)
end
elsif rm?(op, 8)
asm do
emit_byte(0xf6)
emit_modrm(op, 5)
end
else
raise "unsupported IMUL instruction: op=#{op.inspect}"
end
when 2 when 2
dest, src = ops dest, src = ops
@ -594,24 +583,20 @@ module Assembler
end end
end end
# Unsigned multiply.
def mul(op)
group3(op, 4, 'MUL')
end
# TODO implement methods for opcode groups, such as IDIV and IMUL with
# one operand.
# Signed divide.
def idiv(op) def idiv(op)
if rm?(op) group3(op, 7, 'IDIV')
asm do end
emit_byte(0xf7)
emit_modrm(op, 7) # Unsigned divide.
end def div(op)
elsif rm?(op, 8) group3(op, 6, 'DIV')
asm do
emit_byte(0xf6)
emit_modrm(op, 7)
end
else
raise "unsupported IDIV instruction: op=#{op.inspect}"
end
end end
@ -687,26 +672,12 @@ module Assembler
def not_(op) def not_(op)
if rm?(op) group3(op, 2, 'NOT')
asm do
emit_byte(0xf7)
emit_modrm(op, 2)
end
else
raise "unsupported NOT instruction: op=#{op.inspect}"
end
end end
def neg(op) def neg(op)
if rm?(op) group3(op, 3, 'NEG')
asm do
emit_byte(0xf7)
emit_modrm(op, 3)
end
else
raise "unsupported NEG instruction: op=#{op.inspect}"
end
end end
@ -847,6 +818,26 @@ module Assembler
end end
# Opcode group #3. 1-byte opcode, 1 operand (r/m8 or r/m32).
#
# Members of this group are: DIV, IDIV, MUL, IMUL, NEG, NOT, and TEST.
def group3(op, reg, instruction)
opcode =
if rm?(op, 8)
0xf6
elsif rm?(op)
0xf7
else
raise "unsupported #{instruction} instruction: op=#{op.inspect}"
end
asm do
emit_byte(opcode)
emit_modrm(op, reg)
end
end
end # class Binary end # class Binary
end # module Assembler end # module Assembler