From ce48a2d7d90d03c679c31fb940eeb9f860eeb8a4 Mon Sep 17 00:00:00 2001 From: "Ben L. Titzer" Date: Fri, 11 Oct 2024 22:14:26 -0400 Subject: [PATCH] [asm] Add bswap instruction --- lib/asm/x86-64/X86_64Assembler.v3 | 6 ++++++ lib/asm/x86/X86Assembler.v3 | 1 + test/asm/x86-64/X86_64AssemblerTestGen.v3 | 2 ++ 3 files changed, 9 insertions(+) diff --git a/lib/asm/x86-64/X86_64Assembler.v3 b/lib/asm/x86-64/X86_64Assembler.v3 index 11b28cb1f..e3079a167 100644 --- a/lib/asm/x86-64/X86_64Assembler.v3 +++ b/lib/asm/x86-64/X86_64Assembler.v3 @@ -315,6 +315,12 @@ class X86_64Assembler(w: DataWriter, OP_REX: byte) { def add_r_i(a: X86_64Gpr, i: int) -> this { emitop2_r_i(a, i, OP_REX, 0); } def add_m_i(a: X86_64Addr, i: int) -> this { emitop2_m_i(a, i, OP_REX, 0); } + def bswap_r(a: X86_64Gpr) -> this { + var rex = OP_REX | rex_r(a, REX_B); + if (rex != 0) emitb(REX_BYTE | rex); + emitbb(0x0F, 0xC8 + a.low3); + } + def btr_r_i(a: X86_64Gpr, imm: u6) -> this { var rex = OP_REX | rex_r(a, REX_B); if (rex != 0) emitb(REX_BYTE | rex); diff --git a/lib/asm/x86/X86Assembler.v3 b/lib/asm/x86/X86Assembler.v3 index 48321a76a..3919ee944 100644 --- a/lib/asm/x86/X86Assembler.v3 +++ b/lib/asm/x86/X86Assembler.v3 @@ -241,6 +241,7 @@ class X86Assembler(w: DataWriter) { return w.pos; } def bsr(a: X86Reg, b: X86Rm) { emitbb_rm(0x0f, 0xBD, b, a.index); } + def bswap(a: X86Reg) { emitbb(0x0F, 0xC8 + a.index); } def shl_i(a: X86Rm, imm: int) { // shift left by immediate if (imm == 1) return emitb_rm(0xD1, a, 4); emitb_rm(0xC1, a, 4); diff --git a/test/asm/x86-64/X86_64AssemblerTestGen.v3 b/test/asm/x86-64/X86_64AssemblerTestGen.v3 index 4c92e8faa..983e27749 100644 --- a/test/asm/x86-64/X86_64AssemblerTestGen.v3 +++ b/test/asm/x86-64/X86_64AssemblerTestGen.v3 @@ -63,6 +63,8 @@ def main(a: Array) -> int { do_r_dq("bsr", do_r_r, asm.d.bsr_r_r, asm.q.bsr_r_r); do_m_dq("bsr", do_r_m, asm.d.bsr_r_m, asm.q.bsr_r_m); + do_r_dq("bswap", do_r, asm.d.bswap_r, asm.q.bswap_r); + do_r_dq("popcnt", do_r_r, asm.d.popcnt_r_r, asm.q.popcnt_r_r); do_m_dq("popcnt", do_r_m, asm.d.popcnt_r_m, asm.q.popcnt_r_m);