Skip to content

Commit

Permalink
Add support for necessary asm instructions in asm/x86-64
Browse files Browse the repository at this point in the history
  • Loading branch information
khagankhan committed Jul 9, 2024
1 parent fdef808 commit 3b80988
Show file tree
Hide file tree
Showing 2 changed files with 127 additions and 3 deletions.
72 changes: 70 additions & 2 deletions lib/asm/x86-64/X86_64Assembler.v3
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,21 @@ class X86_64Assembler(w: DataWriter, OP_REX: byte) {
def or_m_r(a: X86_64Addr, b: X86_64Gpr) -> this { emitop2_m_r(a, b, OP_REX, 1); }
def or_r_i(a: X86_64Gpr, i: int) -> this { emitop2_r_i(a, i, OP_REX, 1); }
def or_m_i(a: X86_64Addr, i: int) -> this { emitop2_m_i(a, i, OP_REX, 1); }

def orb_m_r(a: X86_64Addr, b: X86_64Gpr) -> this {
var rex = if(b.regnum > 3, REX_BYTE);
emit_rex_b_m_r(a, b, rex, 0x08);
}
def orw_m_r(a: X86_64Addr, b: X86_64Gpr) -> this {
emitb(PREFIX_W);
emit_rex_b_m_r(a, b, NO_REX, 0x09);
}
def ord_m_r(a: X86_64Addr, b: X86_64Gpr) -> this {
emit_rex_b_m_r(a, b, NO_REX, 0x09);
}
def orq_m_r(a: X86_64Addr, b: X86_64Gpr) -> this {
emit_rex_b_m_r(a, b, REX_W, 0x09);
}

def adc_r_r(a: X86_64Gpr, b: X86_64Gpr) -> this { emitop2_r_r(a, b, OP_REX, 2); }
def adc_r_m(a: X86_64Gpr, b: X86_64Addr) -> this { emitop2_r_m(a, b, OP_REX, 2); }
Expand All @@ -351,6 +366,21 @@ class X86_64Assembler(w: DataWriter, OP_REX: byte) {
def and_m_r(a: X86_64Addr, b: X86_64Gpr) -> this { emitop2_m_r(a, b, OP_REX, 4); }
def and_r_i(a: X86_64Gpr, i: int) -> this { emitop2_r_i(a, i, OP_REX, 4); }
def and_m_i(a: X86_64Addr, i: int) -> this { emitop2_m_i(a, i, OP_REX, 4); }

def andb_m_r(a: X86_64Addr, b: X86_64Gpr) -> this {
var rex = if(b.regnum > 3, REX_BYTE);
emit_rex_b_m_r(a, b, rex, 0x20);
}
def andw_m_r(a: X86_64Addr, b: X86_64Gpr) -> this {
emitb(PREFIX_W);
emit_rex_b_m_r(a, b, NO_REX, 0x21);
}
def andd_m_r(a: X86_64Addr, b: X86_64Gpr) -> this {
emit_rex_b_m_r(a, b, NO_REX, 0x21);
}
def andq_m_r(a: X86_64Addr, b: X86_64Gpr) -> this {
emit_rex_b_m_r(a, b, REX_W, 0x21);
}

def sub_r_r(a: X86_64Gpr, b: X86_64Gpr) -> this { emitop2_r_r(a, b, OP_REX, 5); }
def sub_r_m(a: X86_64Gpr, b: X86_64Addr) -> this { emitop2_r_m(a, b, OP_REX, 5); }
Expand All @@ -363,6 +393,21 @@ class X86_64Assembler(w: DataWriter, OP_REX: byte) {
def xor_m_r(a: X86_64Addr, b: X86_64Gpr) -> this { emitop2_m_r(a, b, OP_REX, 6); }
def xor_r_i(a: X86_64Gpr, i: int) -> this { emitop2_r_i(a, i, OP_REX, 6); }
def xor_m_i(a: X86_64Addr, i: int) -> this { emitop2_m_i(a, i, OP_REX, 6); }

def xorb_m_r(a: X86_64Addr, b: X86_64Gpr) -> this {
var rex = if(b.regnum > 3, REX_BYTE);
emit_rex_b_m_r(a, b, rex, 0x30);
}
def xorw_m_r(a: X86_64Addr, b: X86_64Gpr) -> this {
emitb(PREFIX_W);
emit_rex_b_m_r(a, b, NO_REX, 0x31);
}
def xord_m_r(a: X86_64Addr, b: X86_64Gpr) -> this {
emit_rex_b_m_r(a, b, NO_REX, 0x31);
}
def xorq_m_r(a: X86_64Addr, b: X86_64Gpr) -> this {
emit_rex_b_m_r(a, b, REX_W, 0x31);
}

def cmpb_r_r(a: X86_64Gpr, b: X86_64Gpr) -> this { // XXX: factor out common routine
var rex = if(a.regnum > 3 || b.regnum > 3, REX_BYTE, NO_REX);
Expand Down Expand Up @@ -453,6 +498,7 @@ class X86_64Assembler(w: DataWriter, OP_REX: byte) {
def cdq() -> this { emitb(0x99); }
def cqo() -> this { emitbb(REX_BYTE | REX_W, 0x99); }
def lock() -> this { emitb(0xF0); }
def mfence() -> this { emitbbb(0x0F, 0xAE, 0xF0);}

private def checkAbs(m: X86_64Addr) -> int {
if (m.base != null || m.index != null) System.error(ERROR, "expected absolute address");
Expand Down Expand Up @@ -942,6 +988,19 @@ class X86_64Assembler(w: DataWriter, OP_REX: byte) {
def neg_m(a: X86_64Addr) -> this {
emit_rex_b_m_x(a, OP_REX, 0xF7, 3);
}
def negb_m(a: X86_64Addr) -> this {
emit_rex_b_m_x(a, NO_REX, 0xF6, 3);
}
def negw_m(a: X86_64Addr) -> this {
emitb(PREFIX_W);
emit_rex_b_m_x(a, NO_REX, 0xF7, 3);
}
def negd_m(a: X86_64Addr) -> this {
emit_rex_b_m_x(a, NO_REX, 0xF7, 3);
}
def negq_m(a: X86_64Addr) -> this {
emit_rex_b_m_x(a, REX_W, 0xF7, 3);
}
def pushq_m(a: X86_64Addr) -> this {
emit_rex_b_m_x(a, NO_REX, 0xFF, 6);
}
Expand Down Expand Up @@ -1048,7 +1107,7 @@ class X86_64Assembler(w: DataWriter, OP_REX: byte) {
}
emit_rex_b_r_r(b, a, OP_REX, 0x87);
}

def xchgb_m_r(a: X86_64Addr, b: X86_64Gpr) -> this {
var rex = if(b.regnum > 3, REX_BYTE);
emit_rex_b_m_r(a, b, rex, 0x86);
Expand All @@ -1066,13 +1125,22 @@ class X86_64Assembler(w: DataWriter, OP_REX: byte) {
def xchg_m_r(a: X86_64Addr, b: X86_64Gpr) -> this {
emit_rex_b_m_r(a, b, OP_REX, 0x87);
}


def xaddb_m_r(a: X86_64Addr, b: X86_64Gpr) -> this {
var rex = if(b.regnum > 3, REX_BYTE);
emit_rex_bb_r_m(b, a, rex, 0x0F, 0xC0);
}
def xaddw_m_r(a: X86_64Addr, b: X86_64Gpr) -> this {
emitb(PREFIX_W);
emit_rex_bb_r_m(b, a, NO_REX, 0x0F, 0xC1);
}
def xadd_r_r(a: X86_64Gpr, b: X86_64Gpr) -> this {
emit_rex_bb_r_r(b, a, OP_REX, 0x0F, 0xC1);
}
def xadd_m_r(a: X86_64Addr, b: X86_64Gpr) -> this {
emit_rex_bb_r_m(b, a, OP_REX, 0x0F, 0xC1);
}

// SSE arithmetic
// XXX: factor SSE arithmetic further
def paddq_s_s(a: X86_64Xmmr, b: X86_64Xmmr) -> this {
Expand Down
58 changes: 57 additions & 1 deletion test/asm/x86-64/X86_64AssemblerTestGen.v3
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ def main(a: Array<string>) -> int {
do_jmp();

do_cmpxchng();
do_xchng();
do_xadd();
do_xorn();
do_orn();
do_andn();

do_r_dq("xchg", do_r_r, asm.d.xchg_r_r, asm.q.xchg_r_r);
do_m_dq("xchg", do_m_r, asm.d.xchg_m_r, asm.q.xchg_m_r);
Expand Down Expand Up @@ -338,6 +343,57 @@ def do_cmpxchng() {
do_m_r("cmpxchg qword", asm.q.cmpxchg_m_r);
}

def do_xchng() {
regSize = 8;
do_m_r("xchg byte", asm.xchgb_m_r);
regSize = 16;
do_m_r("xchg word", asm.xchgw_m_r);
regSize = 32;
do_m_r("xchg dword", asm.xchgd_m_r);
regSize = 64;
do_m_r("xchg qword", asm.xchgq_m_r);
}

def do_xadd() {
regSize = 8;
do_m_r("xadd byte", asm.xaddb_m_r);
regSize = 16;
do_m_r("xadd word", asm.xaddw_m_r);
}

def do_xorn() {
regSize = 8;
do_m_r("xor byte", asm.xorb_m_r);
regSize = 16;
do_m_r("xor word", asm.xorw_m_r);
regSize = 32;
do_m_r("xor dword", asm.xord_m_r);
regSize = 64;
do_m_r("xor qword", asm.xorq_m_r);
}

def do_orn() {
regSize = 8;
do_m_r("or byte", asm.orb_m_r);
regSize = 16;
do_m_r("or word", asm.orw_m_r);
regSize = 32;
do_m_r("or dword", asm.ord_m_r);
regSize = 64;
do_m_r("or qword", asm.orq_m_r);
}

def do_andn() {
regSize = 8;
do_m_r("and byte", asm.andb_m_r);
regSize = 16;
do_m_r("and word", asm.andw_m_r);
regSize = 32;
do_m_r("and dword", asm.andd_m_r);
regSize = 64;
do_m_r("and qword", asm.andq_m_r);
}

def do_set() {
var buf = StringBuilder.new();
for (cond in X86_64Conds.all) {
Expand Down Expand Up @@ -1009,4 +1065,4 @@ def outln(b: StringBuilder) {
b.ln();
System.fileWriteK(1, b.buf, 0, b.length);
b.reset();
}
}

0 comments on commit 3b80988

Please sign in to comment.