v.gen.native: initial support for the asm statement in the native backend (#11292)
parent
57b148032f
commit
3c85a03b8a
|
@ -37,6 +37,7 @@ enum Register {
|
||||||
|
|
||||||
const (
|
const (
|
||||||
fn_arg_registers = [Register.rdi, .rsi, .rdx, .rcx, .r8, .r9]
|
fn_arg_registers = [Register.rdi, .rsi, .rdx, .rcx, .r8, .r9]
|
||||||
|
amd64_cpuregs = ['eax', 'ecx', 'edx', 'ebx', 'esp', 'ebp', 'esi', 'edi']
|
||||||
)
|
)
|
||||||
|
|
||||||
fn (mut g Gen) dec(reg Register) {
|
fn (mut g Gen) dec(reg Register) {
|
||||||
|
@ -53,6 +54,11 @@ fn (mut g Gen) dec(reg Register) {
|
||||||
g.println('dec $reg')
|
g.println('dec $reg')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[inline]
|
||||||
|
fn byt(n int, s int) byte {
|
||||||
|
return byte((n >> (s * 8)) & 0xff)
|
||||||
|
}
|
||||||
|
|
||||||
fn (mut g Gen) inc(reg Register) {
|
fn (mut g Gen) inc(reg Register) {
|
||||||
g.write16(0xff49)
|
g.write16(0xff49)
|
||||||
match reg {
|
match reg {
|
||||||
|
@ -1038,6 +1044,109 @@ fn (mut g Gen) trap() {
|
||||||
g.println('trap')
|
g.println('trap')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn (mut g Gen) gen_asm_stmt(asm_node ast.AsmStmt) {
|
||||||
|
if g.pref.arch == .arm64 {
|
||||||
|
g.gen_asm_stmt_arm64(asm_node)
|
||||||
|
} else {
|
||||||
|
g.gen_asm_stmt_amd64(asm_node)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (mut g Gen) gen_asm_stmt_amd64(asm_node ast.AsmStmt) {
|
||||||
|
// inline assembly using vasm
|
||||||
|
g.println('// asm inline')
|
||||||
|
mut reg := 0
|
||||||
|
mut imm := 0
|
||||||
|
mut regname := ''
|
||||||
|
// dump(asm_node)
|
||||||
|
for t in asm_node.templates {
|
||||||
|
mut line := t.name
|
||||||
|
mut comma := false
|
||||||
|
for a in t.args {
|
||||||
|
if comma {
|
||||||
|
line += ', '
|
||||||
|
} else {
|
||||||
|
comma = true
|
||||||
|
}
|
||||||
|
match a {
|
||||||
|
ast.AsmRegister {
|
||||||
|
regname = a.name
|
||||||
|
reg = native.amd64_cpuregs.index(regname)
|
||||||
|
line += a.typ.str()
|
||||||
|
}
|
||||||
|
ast.IntegerLiteral {
|
||||||
|
line += a.val
|
||||||
|
imm = a.val.int()
|
||||||
|
}
|
||||||
|
ast.BoolLiteral {
|
||||||
|
line += a.val.str()
|
||||||
|
imm = if a.val { 1 } else { 0 }
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
ast.AsmAddressing {
|
||||||
|
}
|
||||||
|
ast.AsmAlias {
|
||||||
|
}
|
||||||
|
ast.AsmDisp {
|
||||||
|
}
|
||||||
|
ast.CharLiteral {
|
||||||
|
}
|
||||||
|
ast.FloatLiteral {
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
string {
|
||||||
|
// XXX
|
||||||
|
g.v_error('no strings allowed in this context', asm_node.pos)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
g.v_error('unsupported instruction argument argument', asm_node.pos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g.println(': $line')
|
||||||
|
match t.name {
|
||||||
|
'nop' {
|
||||||
|
g.write8(byte(0x90))
|
||||||
|
}
|
||||||
|
'syscall' {
|
||||||
|
g.write8(byte(0x0f))
|
||||||
|
g.write8(byte(0x05))
|
||||||
|
}
|
||||||
|
'ret' {
|
||||||
|
g.write8(byte(0xc3))
|
||||||
|
}
|
||||||
|
'int3' {
|
||||||
|
g.write8(byte(0xcc))
|
||||||
|
g.write8(byte(imm))
|
||||||
|
}
|
||||||
|
'sti' {
|
||||||
|
g.write8(byte(0xfb))
|
||||||
|
}
|
||||||
|
'cli' {
|
||||||
|
g.write8(byte(0xfa))
|
||||||
|
}
|
||||||
|
'int' {
|
||||||
|
g.write8(byte(0xcd))
|
||||||
|
g.write8(byte(imm))
|
||||||
|
}
|
||||||
|
'cpuid' {
|
||||||
|
g.write8(byte(0x0f))
|
||||||
|
g.write8(byte(0xa2))
|
||||||
|
}
|
||||||
|
'mov' {
|
||||||
|
g.write8(byte(0xb8 + reg))
|
||||||
|
g.write8(byt(imm, 0))
|
||||||
|
g.write8(byt(imm, 1))
|
||||||
|
g.write8(byt(imm, 2))
|
||||||
|
g.write8(byt(imm, 3))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
g.v_error('unsupported instruction $t.name', asm_node.pos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn (mut g Gen) gen_assert(assert_node ast.AssertStmt) {
|
fn (mut g Gen) gen_assert(assert_node ast.AssertStmt) {
|
||||||
mut cjmp_addr := 0
|
mut cjmp_addr := 0
|
||||||
mut ine := ast.InfixExpr{}
|
mut ine := ast.InfixExpr{}
|
||||||
|
|
|
@ -197,3 +197,7 @@ pub fn (mut g Gen) gen_arm64_exit(expr ast.Expr) {
|
||||||
g.mov_arm(.x0, 0)
|
g.mov_arm(.x0, 0)
|
||||||
g.svc()
|
g.svc()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn (mut g Gen) gen_asm_stmt_arm64(asm_node ast.AsmStmt) {
|
||||||
|
g.v_error('The asm statement for arm64 not yet implemented', asm_node.pos)
|
||||||
|
}
|
||||||
|
|
|
@ -380,6 +380,9 @@ fn (mut g Gen) stmt(node ast.Stmt) {
|
||||||
g.pop(.rbp)
|
g.pop(.rbp)
|
||||||
g.ret()
|
g.ret()
|
||||||
}
|
}
|
||||||
|
ast.AsmStmt {
|
||||||
|
g.gen_asm_stmt(node)
|
||||||
|
}
|
||||||
ast.AssertStmt {
|
ast.AssertStmt {
|
||||||
g.gen_assert(node)
|
g.gen_assert(node)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
fn asm_test() {
|
||||||
|
asm amd64 {
|
||||||
|
nop
|
||||||
|
}
|
||||||
|
println('inline works')
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
asm_test()
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
inline works
|
Loading…
Reference in New Issue