Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for necessary asm instructions in asm/x86-64 #262

Merged
merged 2 commits into from
Jul 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
70 changes: 69 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,12 @@ def main(a: Array<string>) -> int {
do_jmp();

do_cmpxchng();
do_xchng();
do_xaddn();
do_xorn();
do_orn();
do_andn();
do_negn();

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 +344,68 @@ 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_xaddn() {
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_negn() {
regSize = 8;
do_m("and byte", asm.negb_m);
regSize = 16;
do_m("and word", asm.negw_m);
regSize = 32;
do_m("and dword", asm.negd_m);
regSize = 64;
do_m("and qword", asm.negq_m);
}

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