@@ -457,7 +457,7 @@ fn (op JumpOp) amd64() u16 {
457457fn (mut c Amd64) cjmp (op JumpOp) i32 {
458458 c.g.write16 (op.amd64 ())
459459 pos := c.g.pos ()
460- c.g.write32 (placeholder)
460+ c.g.write32 (placeholder) // will get replaced by the right address
461461 c.g.println ('${op }' )
462462 return i32 (pos)
463463}
@@ -466,7 +466,7 @@ fn (mut c Amd64) jmp(addr i32) i32 {
466466 c.g.write8 (0xe9 )
467467 pos := c.g.pos ()
468468 c.g.write32 (addr) // 0xffffff
469- c.g.println ('jmp' )
469+ c.g.println ('jmp ${ int ( pos + addr ). hex2 ()} ' )
470470 // return the position of jump address for placeholder
471471 return i32 (pos)
472472}
@@ -603,7 +603,7 @@ fn (mut c Amd64) mov_store(regptr Amd64Register, reg Amd64Register, size Size) {
603603 }
604604 c.g.write8 (if size == ._8 { i32 (0x88 ) } else { i32 (0x89 ) })
605605 c.g.write8 (i32 (reg) % 8 * 8 + i32 (regptr) % 8 )
606- c.g.println ('mov [${regptr }], ${reg }' )
606+ c.g.println ('mov [${regptr }], ${reg } ; size:${ size }bits ' )
607607}
608608
609609fn (mut c Amd64) mov_reg_to_var (var Var, r Register, config VarConfig) {
@@ -885,7 +885,7 @@ fn (mut c Amd64) mov_var_to_reg(reg Register, var Var, config VarConfig) {
885885 } else {
886886 c.g.write8 ((0xff - offset + 1 ) % 0x100 )
887887 }
888- c.g.println ('${instruction } ${reg }, ${size_str } PTR [rbp-${int (offset ).hex2 ()}]' )
888+ c.g.println ('${instruction } ${reg }, ${size_str } PTR [rbp-${int (offset ).hex2 ()}] ; `${ var . name }` ' )
889889 }
890890 GlobalVar {
891891 // TODO
@@ -1263,6 +1263,7 @@ pub fn (mut c Amd64) test_reg(r Amd64Register) {
12631263
12641264// return length in .rax of string pointed by given register
12651265pub fn (mut c Amd64) inline_strlen (r Amd64 Register) {
1266+ c.g.println ('; inline_strlen: (reg:${r }) {' )
12661267 c.mov_reg (Amd64 Register.rdi, r)
12671268 c.mov (Amd64 Register.rcx, - 1 )
12681269 c.mov (Amd64 Register.eax, 0 )
@@ -1271,6 +1272,7 @@ pub fn (mut c Amd64) inline_strlen(r Amd64Register) {
12711272 c.dec (.rcx)
12721273 c.mov_reg (Amd64 Register.rax, Amd64 Register.rcx)
12731274 c.g.println ('strlen rax, ${r }' )
1275+ c.g.println ('; inline_strlen }' )
12741276}
12751277
12761278pub fn (mut c Amd64) get_dllcall_addr (import_addr i64 ) i64 {
@@ -1296,6 +1298,7 @@ pub fn (mut c Amd64) dllcall(symbol string) {
12961298}
12971299
12981300fn (mut c Amd64) gen_print (s string , fd i32 ) {
1301+ c.g.println ('; print: (fd:${fd } s:\' ${s }\' ) {' )
12991302 if c.g.pref.os == .windows {
13001303 c.sub (.rsp, 0x38 )
13011304 c.mov (Amd64 Register.rcx, - 10 - fd)
@@ -1317,9 +1320,11 @@ fn (mut c Amd64) gen_print(s string, fd i32) {
13171320 c.mov (Amd64 Register.edx, i32 (s.len)) // len
13181321 c.syscall ()
13191322 }
1323+ c.g.println ('; print }' )
13201324}
13211325
13221326pub fn (mut c Amd64) gen_print_reg (r Register, n i32 , fd i32 ) {
1327+ c.g.println ('; print_reg: (reg:${r } fd:${fd } len:${n }) {' )
13231328 str_reg := if c.g.pref.os == .windows { Amd64 Register.rdx } else { Amd64 Register.rsi }
13241329 len_reg := if c.g.pref.os == .windows { Amd64 Register.r8 } else { Amd64 Register.rdx }
13251330 c.mov_reg (str_reg, r)
@@ -1347,6 +1352,7 @@ pub fn (mut c Amd64) gen_print_reg(r Register, n i32, fd i32) {
13471352 c.mov (Amd64 Register.edi, fd)
13481353 c.syscall ()
13491354 }
1355+ c.g.println ('; print_reg }' )
13501356}
13511357
13521358pub fn (mut c Amd64) gen_exit (expr ast.Expr) {
@@ -1590,10 +1596,9 @@ fn (mut c Amd64) div_reg(a Amd64Register, b Amd64Register) {
15901596 c.g.write8 (0xf8 )
15911597 }
15921598 .rbx {
1593- c.mov (Amd64 Register.edx, 0 )
15941599 c.g.write8 (0x48 )
15951600 c.g.write8 (0xf7 )
1596- c.g.write8 (0xfb ) // idiv ebx
1601+ c.g.write8 (0xfb )
15971602 }
15981603 .rdx {
15991604 c.g.write8 (0x48 )
@@ -1937,8 +1942,8 @@ pub fn (mut c Amd64) call_fn(node ast.CallExpr) {
19371942}
19381943
19391944fn (mut c Amd64) call_builtin (name Builtin) i64 {
1940- call_addr := c. call ( 0 )
1941- c.g. println ( ' call builtin `${ name }`' )
1945+ c.g. println ( '; call builtin `${ name }`: (the 0 will get replaced)' )
1946+ call_addr := c. call ( 0 ) // the 0 will get replaced by the right addr when the function will be generated
19421947 return call_addr
19431948}
19441949
@@ -3478,6 +3483,13 @@ fn (mut c Amd64) convert_int_to_string(a Register, b Register) {
34783483 c.g.write8 (0x30 )
34793484 c.g.println ("mov BYTE PTR [rdi], '0'" )
34803485
3486+ // null terminate the string
3487+ c.inc (.rdi)
3488+ c.g.write8 (0xc6 )
3489+ c.g.write8 (0x07 )
3490+ c.g.write8 (0x0 )
3491+ c.g.println ('mov BYTE PTR [rdi], `\0`' )
3492+
34813493 end_label := c.g.labels.new_label ()
34823494 end_jmp_addr := c.jmp (0 )
34833495 c.g.labels.patches << LabelPatch{
@@ -3513,32 +3525,18 @@ fn (mut c Amd64) convert_int_to_string(a Register, b Register) {
35133525 c.g.labels.addrs[skip_minus_label] = c.g.pos ()
35143526 c.g.println ('; label ${skip_minus_label }' )
35153527
3516- c.mov_reg (Amd64 Register.r12 , Amd64 Register.rdi) // copy the buffer position to r12
3528+ c.mov_reg (Amd64 Register.r12 , Amd64 Register.rdi) // copy the buffer position (start of the number without `-`) to r12
35173529
35183530 loop_label := c.g.labels.new_label ()
35193531 loop_start := c.g.pos ()
35203532 c.g.println ('; label ${loop_label }' )
35213533
3522- c.push (Amd64 Register.rax)
3523-
3524- c.mov (Amd64 Register.rdx, 0 )
3534+ c.mov (Amd64 Register.rdx, 0 ) // upperhalf of the dividend
35253535 c.mov (Amd64 Register.rbx, 10 )
3526- c.div_reg (.rax, .rbx)
3527- c.add8 (.rdx, '0' [ 0 ])
3536+ c.div_reg (.rax, .rbx) // rax will be the result of the division
3537+ c.add8 (.rdx, i32 ( `0` )) // rdx is the remainder, add 48 to convert it into it's ascii representation
35283538
3529- c.g.write8 (0x66 )
3530- c.g.write8 (0x89 )
3531- c.g.write8 (0x17 )
3532- c.g.println ('mov BYTE PTR [rdi], rdx' )
3533-
3534- // divide the integer in rax by 10 for next iteration
3535- c.pop (.rax)
3536- c.mov (Amd64 Register.rbx, 10 )
3537- c.cdq ()
3538- c.g.write8 (0x48 )
3539- c.g.write8 (0xf7 )
3540- c.g.write8 (0xfb )
3541- c.g.println ('idiv rbx' )
3539+ c.mov_store (.rdi, .rdx, ._8 )
35423540
35433541 // go to the next character
35443542 c.inc (.rdi)
@@ -3550,9 +3548,15 @@ fn (mut c Amd64) convert_int_to_string(a Register, b Register) {
35503548 id: loop_label
35513549 pos: loop_cjmp_addr
35523550 }
3553- c.g.println ('; jump to label ${skip_minus_label }' )
3551+ c.g.println ('; jump to label ${loop_label }' )
35543552 c.g.labels.addrs[loop_label] = loop_start
35553553
3554+ // null terminate the string
3555+ c.g.write8 (0xc6 )
3556+ c.g.write8 (0x07 )
3557+ c.g.write8 (0x0 )
3558+ c.g.println ('mov BYTE PTR [rdi], `\0`' )
3559+
35563560 // after all was converted, reverse the string
35573561 reg := c.g.get_builtin_arg_reg (.reverse_string, 0 ) as Amd64Register
35583562 c.mov_reg (reg, Amd64 Register.r12 )
@@ -3569,8 +3573,6 @@ fn (mut c Amd64) reverse_string(r Register) {
35693573 c.mov_reg (Amd64 Register.rdi, reg)
35703574 }
35713575
3572- c.mov (Amd64 Register.eax, 0 )
3573-
35743576 c.g.write8 (0x48 )
35753577 c.g.write8 (0x8d )
35763578 c.g.write8 (0x48 )
@@ -3579,9 +3581,9 @@ fn (mut c Amd64) reverse_string(r Register) {
35793581
35803582 c.mov_reg (Amd64 Register.rsi, Amd64 Register.rdi)
35813583
3582- c.g. write8 ( 0xf2 )
3583- c.g. write8 ( 0xae )
3584- c.g. println ( 'repnz scas al, BYTE PTR es:[rdi]' )
3584+ // search for null at end of string
3585+ c.mov (Amd 64 Register.eax, 0 )
3586+ c.cld_repne_scasb ( )
35853587
35863588 c.sub8 (.rdi, 0x2 )
35873589 c.cmp_reg (.rdi, .rsi)
0 commit comments