mirror of
https://github.com/vlang/v.git
synced 2025-09-13 22:42:26 +03:00
fixes, more struct assigns
This commit is contained in:
parent
39bb76b12c
commit
3ae4f24d8e
1 changed files with 111 additions and 35 deletions
|
@ -139,7 +139,7 @@ fn (mut c Amd64) dec(reg Amd64Register) {
|
||||||
.rsi { c.g.write8(0xce) }
|
.rsi { c.g.write8(0xce) }
|
||||||
.rdi { c.g.write8(0xcf) }
|
.rdi { c.g.write8(0xcf) }
|
||||||
.r12 { c.g.write8(0xc4) }
|
.r12 { c.g.write8(0xc4) }
|
||||||
else { panic('unhandled inc ${reg}') }
|
else { c.g.n_error('unhandled inc ${reg}') }
|
||||||
}
|
}
|
||||||
c.g.println('dec ${reg}')
|
c.g.println('dec ${reg}')
|
||||||
}
|
}
|
||||||
|
@ -156,7 +156,7 @@ fn (mut c Amd64) neg(reg Amd64Register) {
|
||||||
c.g.write8(0xf7)
|
c.g.write8(0xf7)
|
||||||
match reg {
|
match reg {
|
||||||
.rax { c.g.write8(0xd8) }
|
.rax { c.g.write8(0xd8) }
|
||||||
else { panic('unhandled neg ${reg}') }
|
else { c.g.n_error('unhandled neg ${reg}') }
|
||||||
}
|
}
|
||||||
c.g.println('neg ${reg}')
|
c.g.println('neg ${reg}')
|
||||||
}
|
}
|
||||||
|
@ -172,7 +172,7 @@ fn (mut c Amd64) cmp(reg Amd64Register, size Size, val i64) {
|
||||||
// see https://www.sandpile.org/x86/opc_rm.htm for a table for modr/m byte (at the bottom of the second one)
|
// see https://www.sandpile.org/x86/opc_rm.htm for a table for modr/m byte (at the bottom of the second one)
|
||||||
|
|
||||||
if c.g.pref.arch != .amd64 {
|
if c.g.pref.arch != .amd64 {
|
||||||
panic('cmp')
|
c.g.n_error('cmp')
|
||||||
}
|
}
|
||||||
// Second byte depends on the size of the value
|
// Second byte depends on the size of the value
|
||||||
match size {
|
match size {
|
||||||
|
@ -185,7 +185,7 @@ fn (mut c Amd64) cmp(reg Amd64Register, size Size, val i64) {
|
||||||
c.g.write8(0x81) // compares a 64bits register with a 32bits immediate value
|
c.g.write8(0x81) // compares a 64bits register with a 32bits immediate value
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
panic('unhandled cmp size ${size}')
|
c.g.n_error('unhandled cmp size ${size}')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Third byte (modr/m byte) depends on the regiister being compared to
|
// Third byte (modr/m byte) depends on the regiister being compared to
|
||||||
|
@ -196,7 +196,7 @@ fn (mut c Amd64) cmp(reg Amd64Register, size Size, val i64) {
|
||||||
.rcx { c.g.write8(0xf9) }
|
.rcx { c.g.write8(0xf9) }
|
||||||
.rdx { c.g.write8(0xfa) }
|
.rdx { c.g.write8(0xfa) }
|
||||||
.rbx { c.g.write8(0xfb) }
|
.rbx { c.g.write8(0xfb) }
|
||||||
else { panic('unhandled cmp reg ${reg}') }
|
else { c.g.n_error('unhandled cmp reg ${reg}') }
|
||||||
}
|
}
|
||||||
match size {
|
match size {
|
||||||
._8 {
|
._8 {
|
||||||
|
@ -206,7 +206,7 @@ fn (mut c Amd64) cmp(reg Amd64Register, size Size, val i64) {
|
||||||
c.g.write32(i32(val))
|
c.g.write32(i32(val))
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
panic('unhandled cmp size ${size}')
|
c.g.n_error('unhandled cmp size ${size}')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c.g.println('cmp ${reg}, ${val}')
|
c.g.println('cmp ${reg}, ${val}')
|
||||||
|
@ -1239,7 +1239,7 @@ fn (mut c Amd64) syscall() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut c Amd64) svc() {
|
fn (mut c Amd64) svc() {
|
||||||
panic('the svc instruction is not available with amd64')
|
c.g.n_error('the svc instruction is not available with amd64')
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut c Amd64) cdq() {
|
fn (mut c Amd64) cdq() {
|
||||||
|
@ -1755,7 +1755,7 @@ fn (mut c Amd64) mov(r Register, val i32) {
|
||||||
|
|
||||||
fn (mut c Amd64) mul_reg(a Amd64Register, b Amd64Register) {
|
fn (mut c Amd64) mul_reg(a Amd64Register, b Amd64Register) {
|
||||||
if a != .rax {
|
if a != .rax {
|
||||||
panic('mul always operates on rax')
|
c.g.n_error('mul always operates on rax')
|
||||||
}
|
}
|
||||||
match b {
|
match b {
|
||||||
.rax {
|
.rax {
|
||||||
|
@ -1763,18 +1763,23 @@ fn (mut c Amd64) mul_reg(a Amd64Register, b Amd64Register) {
|
||||||
c.g.write8(0xf7)
|
c.g.write8(0xf7)
|
||||||
c.g.write8(0xe8)
|
c.g.write8(0xe8)
|
||||||
}
|
}
|
||||||
|
.rcx {
|
||||||
|
c.g.write8(0x48)
|
||||||
|
c.g.write8(0xf7)
|
||||||
|
c.g.write8(0xe9)
|
||||||
|
}
|
||||||
|
.rdx {
|
||||||
|
c.g.write8(0x48)
|
||||||
|
c.g.write8(0xf7)
|
||||||
|
c.g.write8(0xea)
|
||||||
|
}
|
||||||
.rbx {
|
.rbx {
|
||||||
c.g.write8(0x48)
|
c.g.write8(0x48)
|
||||||
c.g.write8(0xf7)
|
c.g.write8(0xf7)
|
||||||
c.g.write8(0xeb)
|
c.g.write8(0xeb)
|
||||||
}
|
}
|
||||||
.rdx {
|
|
||||||
c.g.write8(0x48)
|
|
||||||
c.g.write8(0xf7)
|
|
||||||
c.g.write8(0xe2)
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
panic('unhandled mul ${b}')
|
c.g.n_error('${@LOCATION} unhandled mul ${b}')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c.g.println('mul ${b}')
|
c.g.println('mul ${b}')
|
||||||
|
@ -1789,14 +1794,14 @@ fn (mut c Amd64) imul_reg(r Amd64Register) {
|
||||||
c.g.println('imul ${r}')
|
c.g.println('imul ${r}')
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
panic('unhandled imul ${r}')
|
c.g.n_error('unhandled imul ${r}')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut c Amd64) div_reg(a Amd64Register, b Amd64Register) {
|
fn (mut c Amd64) div_reg(a Amd64Register, b Amd64Register) {
|
||||||
if a != .rax {
|
if a != .rax {
|
||||||
panic('div always operates on rax')
|
c.g.n_error('div always operates on rax')
|
||||||
}
|
}
|
||||||
match b {
|
match b {
|
||||||
.rax {
|
.rax {
|
||||||
|
@ -1804,18 +1809,23 @@ fn (mut c Amd64) div_reg(a Amd64Register, b Amd64Register) {
|
||||||
c.g.write8(0xf7)
|
c.g.write8(0xf7)
|
||||||
c.g.write8(0xf8)
|
c.g.write8(0xf8)
|
||||||
}
|
}
|
||||||
|
.rcx {
|
||||||
|
c.g.write8(0x48)
|
||||||
|
c.g.write8(0xf7)
|
||||||
|
c.g.write8(0xf9)
|
||||||
|
}
|
||||||
|
.rdx {
|
||||||
|
c.g.write8(0x48)
|
||||||
|
c.g.write8(0xf7)
|
||||||
|
c.g.write8(0xfa)
|
||||||
|
}
|
||||||
.rbx {
|
.rbx {
|
||||||
c.g.write8(0x48)
|
c.g.write8(0x48)
|
||||||
c.g.write8(0xf7)
|
c.g.write8(0xf7)
|
||||||
c.g.write8(0xfb)
|
c.g.write8(0xfb)
|
||||||
}
|
}
|
||||||
.rdx {
|
|
||||||
c.g.write8(0x48)
|
|
||||||
c.g.write8(0xf7)
|
|
||||||
c.g.write8(0xf2)
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
panic('unhandled div ${b}')
|
c.g.n_error('unhandled div ${b}')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c.g.println('div ${b}')
|
c.g.println('div ${b}')
|
||||||
|
@ -1923,7 +1933,7 @@ fn (mut c Amd64) sar8(r Amd64Register, val u8) {
|
||||||
c.g.write8(0xfa)
|
c.g.write8(0xfa)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
panic('unhandled sar ${r}, ${val}')
|
c.g.n_error('unhandled sar ${r}, ${val}')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c.g.write8(val)
|
c.g.write8(val)
|
||||||
|
@ -2274,17 +2284,19 @@ fn (mut c Amd64) assign_var(var IdentVar, raw_type ast.Type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Could be nice to have left as an expr to be able to take all int assigns
|
// Could be nice to have left as an expr to be able to take all int assigns
|
||||||
// TODO: Will have a problem if the literal is bigger than max_i64: needs u64
|
// TODO: may have a problem if the literal is bigger than max_i64: needs u64
|
||||||
fn (mut c Amd64) assign_ident_int_lit(node ast.AssignStmt, i i32, int_lit ast.IntegerLiteral, left ast.Ident) {
|
fn (mut c Amd64) assign_ident_int_lit(node ast.AssignStmt, i i32, int_lit ast.IntegerLiteral, left ast.Ident) {
|
||||||
match node.op {
|
match node.op {
|
||||||
.plus_assign {
|
.plus_assign {
|
||||||
c.mov_var_to_reg(Amd64Register.rax, left)
|
c.mov_var_to_reg(Amd64Register.rax, left)
|
||||||
c.add(Amd64Register.rax, i32(int_lit.val.int()))
|
c.mov64(Amd64Register.rdx, i64(int_lit.val.int()))
|
||||||
|
c.add_reg(Amd64Register.rax, Amd64Register.rdx)
|
||||||
c.mov_reg_to_var(left, Amd64Register.rax)
|
c.mov_reg_to_var(left, Amd64Register.rax)
|
||||||
}
|
}
|
||||||
.minus_assign {
|
.minus_assign {
|
||||||
c.mov_var_to_reg(Amd64Register.rax, left)
|
c.mov_var_to_reg(Amd64Register.rax, left)
|
||||||
c.sub(.rax, i32(int_lit.val.int()))
|
c.mov64(Amd64Register.rdx, i64(int_lit.val.int()))
|
||||||
|
c.sub_reg(Amd64Register.rax, Amd64Register.rdx)
|
||||||
c.mov_reg_to_var(left, Amd64Register.rax)
|
c.mov_reg_to_var(left, Amd64Register.rax)
|
||||||
}
|
}
|
||||||
.mult_assign {
|
.mult_assign {
|
||||||
|
@ -2330,6 +2342,36 @@ fn (mut c Amd64) assign_ident_int_lit(node ast.AssignStmt, i i32, int_lit ast.In
|
||||||
c.shr_reg(.rax, .rcx)
|
c.shr_reg(.rax, .rcx)
|
||||||
c.mov_reg_to_var(left, Amd64Register.rax)
|
c.mov_reg_to_var(left, Amd64Register.rax)
|
||||||
}
|
}
|
||||||
|
.xor_assign {
|
||||||
|
c.mov_var_to_reg(Amd64Register.rax, left)
|
||||||
|
c.mov64(Amd64Register.rcx, i64(int_lit.val.int()))
|
||||||
|
c.bitxor_reg(.rax, .rcx)
|
||||||
|
c.mov_reg_to_var(left, Amd64Register.rax)
|
||||||
|
}
|
||||||
|
.or_assign {
|
||||||
|
c.mov_var_to_reg(Amd64Register.rax, left)
|
||||||
|
c.mov64(Amd64Register.rcx, i64(int_lit.val.int()))
|
||||||
|
c.bitor_reg(.rax, .rcx)
|
||||||
|
c.mov_reg_to_var(left, Amd64Register.rax)
|
||||||
|
}
|
||||||
|
.and_assign {
|
||||||
|
c.mov_var_to_reg(Amd64Register.rax, left)
|
||||||
|
c.mov64(Amd64Register.rcx, i64(int_lit.val.int()))
|
||||||
|
c.bitand_reg(.rax, .rcx)
|
||||||
|
c.mov_reg_to_var(left, Amd64Register.rax)
|
||||||
|
}
|
||||||
|
.boolean_and_assign {
|
||||||
|
c.mov_var_to_reg(Amd64Register.rax, left)
|
||||||
|
c.mov64(Amd64Register.rcx, i64(int_lit.val.int()))
|
||||||
|
c.bitand_reg(.rax, .rcx)
|
||||||
|
c.mov_reg_to_var(left, Amd64Register.rax)
|
||||||
|
}
|
||||||
|
.boolean_or_assign {
|
||||||
|
c.mov_var_to_reg(Amd64Register.rax, left)
|
||||||
|
c.mov64(Amd64Register.rcx, i64(int_lit.val.int()))
|
||||||
|
c.bitor_reg(.rax, .rcx)
|
||||||
|
c.mov_reg_to_var(left, Amd64Register.rax)
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
c.g.n_error('${@LOCATION} unexpected assignment op ${node.op}')
|
c.g.n_error('${@LOCATION} unexpected assignment op ${node.op}')
|
||||||
}
|
}
|
||||||
|
@ -2981,10 +3023,12 @@ fn (mut c Amd64) assign_stmt(node ast.AssignStmt) {
|
||||||
c.assign_ident_right_expr(node, i32(i), val, left.name, left)
|
c.assign_ident_right_expr(node, i32(i), val, left.name, left)
|
||||||
} else {
|
} else {
|
||||||
if c.g.is_register_type(var_type) {
|
if c.g.is_register_type(var_type) {
|
||||||
c.g.gen_left_value(left)
|
|
||||||
c.push(c.main_reg()) // rax here, stores effective address of the left expr
|
|
||||||
c.g.expr(val)
|
c.g.expr(val)
|
||||||
c.pop(.rdx) // effective address of left expr
|
c.push(c.main_reg())
|
||||||
|
c.g.gen_left_value(left)
|
||||||
|
c.mov_reg(Amd64Register.rdx, Amd64Register.rax) // effective address of the left expr
|
||||||
|
c.mov_deref(Amd64Register.rax, Amd64Register.rdx, var_type) // value of left expr
|
||||||
|
c.pop(.rcx) // value of right expr
|
||||||
c.gen_type_promotion(node.right_types[0], var_type)
|
c.gen_type_promotion(node.right_types[0], var_type)
|
||||||
|
|
||||||
size := match c.g.get_type_size(var_type) {
|
size := match c.g.get_type_size(var_type) {
|
||||||
|
@ -2995,28 +3039,60 @@ fn (mut c Amd64) assign_stmt(node ast.AssignStmt) {
|
||||||
}
|
}
|
||||||
match node.op {
|
match node.op {
|
||||||
.decl_assign, .assign {
|
.decl_assign, .assign {
|
||||||
c.mov_store(.rdx, .rax, size)
|
c.mov_store(.rdx, .rcx, size)
|
||||||
}
|
}
|
||||||
.plus_assign {
|
.plus_assign {
|
||||||
c.mov_deref(Amd64Register.rcx, Amd64Register.rdx, var_type)
|
|
||||||
c.add_reg(.rax, .rcx)
|
c.add_reg(.rax, .rcx)
|
||||||
c.mov_store(.rdx, .rax, size)
|
c.mov_store(.rdx, .rax, size)
|
||||||
}
|
}
|
||||||
.minus_assign {
|
.minus_assign {
|
||||||
c.mov_deref(Amd64Register.rcx, Amd64Register.rdx, var_type)
|
|
||||||
c.sub_reg(.rax, .rcx)
|
c.sub_reg(.rax, .rcx)
|
||||||
c.mov_store(.rdx, .rax, size)
|
c.mov_store(.rdx, .rax, size)
|
||||||
}
|
}
|
||||||
.and_assign {
|
.and_assign {
|
||||||
c.mov_deref(Amd64Register.rcx, Amd64Register.rdx, var_type)
|
|
||||||
c.bitand_reg(.rax, .rcx)
|
c.bitand_reg(.rax, .rcx)
|
||||||
c.mov_store(.rdx, .rax, size)
|
c.mov_store(.rdx, .rax, size)
|
||||||
}
|
}
|
||||||
.mod_assign {
|
.mod_assign {
|
||||||
c.mov_deref(Amd64Register.rcx, Amd64Register.rdx, var_type)
|
|
||||||
c.mod_reg(.rax, .rcx)
|
c.mod_reg(.rax, .rcx)
|
||||||
c.mov_store(.rdx, .rax, size)
|
c.mov_store(.rdx, .rax, size)
|
||||||
}
|
}
|
||||||
|
.mult_assign {
|
||||||
|
c.mul_reg(.rax, .rcx)
|
||||||
|
c.mov_store(.rdx, .rax, size)
|
||||||
|
}
|
||||||
|
.div_assign {
|
||||||
|
c.div_reg(.rax, .rcx)
|
||||||
|
c.mov_store(.rdx, .rax, size)
|
||||||
|
}
|
||||||
|
.xor_assign {
|
||||||
|
c.bitxor_reg(.rax, .rcx)
|
||||||
|
c.mov_store(.rdx, .rax, size)
|
||||||
|
}
|
||||||
|
.or_assign {
|
||||||
|
c.bitor_reg(.rax, .rcx)
|
||||||
|
c.mov_store(.rdx, .rax, size)
|
||||||
|
}
|
||||||
|
.right_shift_assign {
|
||||||
|
c.shr_reg(.rax, .rcx)
|
||||||
|
c.mov_store(.rdx, .rax, size)
|
||||||
|
}
|
||||||
|
.left_shift_assign {
|
||||||
|
c.shl_reg(.rax, .rcx)
|
||||||
|
c.mov_store(.rdx, .rax, size)
|
||||||
|
}
|
||||||
|
.unsigned_right_shift_assign {
|
||||||
|
c.sar_reg(.rax, .rcx)
|
||||||
|
c.mov_store(.rdx, .rax, size)
|
||||||
|
}
|
||||||
|
.boolean_and_assign {
|
||||||
|
c.bitand_reg(.rax, .rcx)
|
||||||
|
c.mov_store(.rdx, .rax, size)
|
||||||
|
}
|
||||||
|
.boolean_or_assign {
|
||||||
|
c.bitor_reg(.rax, .rcx)
|
||||||
|
c.mov_store(.rdx, .rax, size)
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
c.g.n_error('${@LOCATION} Unsupported assign instruction (${node.op})')
|
c.g.n_error('${@LOCATION} Unsupported assign instruction (${node.op})')
|
||||||
}
|
}
|
||||||
|
@ -4767,5 +4843,5 @@ fn (mut c Amd64) cmp_to_stack_top(reg Register) {
|
||||||
|
|
||||||
// Temporary!
|
// Temporary!
|
||||||
fn (mut c Amd64) adr(r Arm64Register, delta i32) {
|
fn (mut c Amd64) adr(r Arm64Register, delta i32) {
|
||||||
panic('`adr` instruction not supported with amd64')
|
c.g.n_error('`adr` instruction not supported with amd64')
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue