A native-only x86-64 code emitter for MoonBit.
///|
test {
let ctx = @asm.JITContext::new()
ctx.mov(@asm.reg(@asm.rax), @asm.imm32(18))
ctx.add(@asm.reg(@asm.rax), @asm.imm32(4))
ctx.sub(@asm.reg(@asm.rax), @asm.imm32(2))
ctx.imul(@asm.reg(@asm.rax), @asm.imm32(3))
ctx.ret()
let fn0 = ctx.finalize_fn_i64()
assert_eq(fn0.call(), 60)
}///|
test {
let ctx = @asm.JITContext::new()
ctx.mov(@asm.reg(@asm.r8), @asm.imm64(42L))
ctx.mov(@asm.mem64(base=@asm.rsp, disp=8), @asm.reg(@asm.r8))
ctx.mov(@asm.reg(@asm.rax), @asm.mem64(base=@asm.rsp, disp=8))
ctx.ret()
}///|
test {
let ctx = @asm.JITContext::new()
let target = ctx.label()
ctx.call(target.target())
assert_eq(ctx.bytes().length(), 5)
}///|
test {
let ctx = @asm.JITContext::new()
ctx.nop()
ctx.ret()
let trace = ctx.trace()
let expected : Array[@asm.Instr] = [NopOp90, RetNearOpC3]
assert_true(trace == expected)
trace.push(SyscallOp0F05)
assert_true(ctx.trace() == expected)
}pub(all) suberror ASMContextError {
UnsupportedAddOperands(Operand, Operand)
UnsupportedSubOperands(Operand, Operand)
UnsupportedXorOperands(Operand, Operand)
UnsupportedMulOperand(Operand)
UnsupportedIncOperand(Operand)
UnsupportedDecOperand(Operand)
LoopRel8OutOfRange(Int)
UnsupportedIMulOperands(Operand, Operand)
UnsupportedMovOperands(Operand, Operand)
UnsupportedPushOperand(Operand)
UnsupportedPopOperand(Operand)
ExecutableMemoryAllocationFailed(UInt64, Int)
GeneratedCodeExceedsMemory(UInt64, UInt64)
ExecutableMemoryProtectionFailed(UInt64, UInt64, Int)
JITContextAlreadyFinalized
UnsupportedOperandWidth(Operand)
OperandWidthMismatch(Width, Width)
ImmediateOutOfRange(Immediate)
InvalidMemoryScale(Int)
InvalidMemoryBase(Register)
InvalidMemoryIndex(Register)
MemoryIndexCannotBeStackPointer(Register)
High8RexConflict
} derive(Debug)pub(all) enum Instr {
RetNearOpC3
NopOp90
SyscallOp0F05
CallRel32OpE8(Target, Int)
LoopRcxRel8OpE2(Label, Int)
MovRm8Reg8Op88(Operand, Register)
MovRmRegOp89(Operand, Register)
MovReg8Rm8Op8A(Register, Operand)
MovRegRmOp8B(Register, Operand)
MovReg8Imm8OpB0(Register, Immediate)
MovRegImmOpB8(Register, Immediate)
MovRm8Imm8OpC6Ext0(Operand, Immediate)
MovRmImmOpC7Ext0(Operand, Immediate)
AddRm8Reg8Op00(Operand, Register)
AddRmRegOp01(Operand, Register)
AddReg8Rm8Op02(Register, Operand)
AddRegRmOp03(Register, Operand)
AddRm8Imm8Op80Ext0(Operand, Immediate)
AddRmImmOp81Ext0(Operand, Immediate)
AddRmImm8SignExtOp83Ext0(Operand, Immediate)
SubRm8Reg8Op28(Operand, Register)
SubRmRegOp29(Operand, Register)
SubReg8Rm8Op2A(Register, Operand)
SubRegRmOp2B(Register, Operand)
SubRm8Imm8Op80Ext5(Operand, Immediate)
SubRmImmOp81Ext5(Operand, Immediate)
SubRmImm8SignExtOp83Ext5(Operand, Immediate)
XorRm8Reg8Op30(Operand, Register)
XorRmRegOp31(Operand, Register)
XorReg8Rm8Op32(Register, Operand)
XorRegRmOp33(Register, Operand)
XorRm8Imm8Op80Ext6(Operand, Immediate)
XorRmImmOp81Ext6(Operand, Immediate)
XorRmImm8SignExtOp83Ext6(Operand, Immediate)
MulRm8OpF6Ext4(Operand)
MulRmOpF7Ext4(Operand)
IMulRegRmOp0FAF(Register, Operand)
IMulRegRmImm8Op6B(Register, Operand, Immediate)
IMulRegRmImmOp69(Register, Operand, Immediate)
IncRm8OpFEExt0(Operand)
IncRmOpFFExt0(Operand)
DecRm8OpFEExt1(Operand)
DecRmOpFFExt1(Operand)
PushRegOp50(Register)
PushRmOpFFExt6(Operand)
PushImm8Op6A(Immediate)
PushImmOp68(Immediate)
PopRegOp58(Register)
PopRmOp8FExt0(Operand)
} derive(Eq, Debug)type JITContexttype JITFunction[T]fn linux_syscall_number(name : String) -> Int?