diff options
Diffstat (limited to 'tnslc')
-rw-r--r-- | tnslc/simple.tnsl | 27 | ||||
-rw-r--r-- | tnslc/tnslc.tnsl | 65 |
2 files changed, 79 insertions, 13 deletions
diff --git a/tnslc/simple.tnsl b/tnslc/simple.tnsl index b140c7a..d871e92 100644 --- a/tnslc/simple.tnsl +++ b/tnslc/simple.tnsl @@ -1,15 +1,18 @@ {}uint8 str1 = "abcd" -{}uint8 str2 = "abce" - -/; main [int] - /; loop (int i = 0; i < 4) [i++] - /; if (str1{i} !== str2{i}) - /; if (str2{i} == 'e') - return 3 - ;/ - return 1 - ;/ - ;/ - return 0 +{}uint8 str2 = "abcd" + +/; call_me [int] + return 4 +;/ + +/; main (int argc, ~~uint argv) [int] + # On windows, the first two arguments are passed in RCX and RDX, so we need to + # update their positions here or else tnsl willhave garbage values in r8 and r9 + asm "mov r8, rcx" + asm "mov r9, rdx" + # If on linux, you would use rdi and rsi instead of rcx and rdx, respectively + + # return the number of arguments + return argc ;/ diff --git a/tnslc/tnslc.tnsl b/tnslc/tnslc.tnsl index df2eb54..9eee55a 100644 --- a/tnslc/tnslc.tnsl +++ b/tnslc/tnslc.tnsl @@ -1504,6 +1504,10 @@ ;out = out + self.vars{i}.norm_size() ;/ ;/ + + /; if (!(self.is_cf()) && !(self.r)) + ;return out + 80 + ;/ ;return out ;/ @@ -1521,6 +1525,65 @@ ;{}uint8 intro = "\tpush rbp\n\tlea rbp, [rsp + 8]\n\tpush r8\n\tpush r9\n\tpush r10\n\tpush r11\n\tpush r12\n\tpush r13\n\tpush r14\n\tpush r15\n" ;out`.csec = string_add(out`.csec, intro) ;/ + + # pre-stack loop + /; loop (int i = 0; i < len (self.vars)) [i++] + ;int loc = self.next_loc(self.vars{i}.data_type) + /; if (loc !< 0) + ;self.vars{i}.location = loc + ;self.vars{i}.loc_type = LOCATION.REGISTER + ;out`.csec = string_join( { + out`.csec, + "\tmov ", get_reg(loc, 8), ", ", get_reg(loc - 8, 8), "\n" + }, "") + ;/ + ;/ + + ;int accum = 0 + /; if (!(self.r)) + ;accum = 80 + ;/ + + ;{}uint8 moves = string_join( { + "lea rsi, [rbp]\n" + }, "") + + # Move extra variables + /; loop (int i = len (self.vars) - 1; i !< 0) [i = i - 1] + /; if (self.vars{i}.loc_type == LOCATION.LITERAL) + ;self.vars{i}.loc_type = LOCATION.STACK + ;int sz = self.vars{i}.norm_size() + ;accum = accum + sz + ;self.vars{i}.location = accum + /; if (len (self.vars{i}.data_type.ptr_chain) > 0) + ;moves.csec = string_join( { + moves.csec, + "\tmov rdi, qword [rsi]\n", + "\tmov qword [rbp - ", int_to_string(accum), "], rdi\n", + "\tadd rsi, 8\n" + }, "") + ;; else if (self.vars{i}.is_prim()) + ;moves.csec = string_join( { + moves.csec, + "\tmov ", get_reg(5, sz), ", ", mov_by_size(sz), "[rsi]\n", + "\tmov ", mov_by_size(sz), "[rbp - ", int_to_string(accum), "], ", get_reg(5, sz),"\n", + "\tadd rsi, ", int_to_string(sz), "\n" + }, "") + ;; else + ;moves.csec = string_join( { + moves.csec, + "\tlea rdi, [rbp - ", int_to_string(accum), "]\n", + "\tmov rcx", int_to_string(sz), "\n", + "\tmovsb\n", + "\tadd rsi, ", int_to_string(sz), "\n" + }, "") + ;/ + ;/ + ;/ + + /; if (accum > 80 && !(self.r)) + ;out`.csec = string_add(out`.csec, moves) + ;/ ;/ /; end_scope (~CompData out) @@ -2000,7 +2063,7 @@ /; loop (cur` = next_non_nl(tok, cur` + 1); cur` < max) [cur` = next_non_nl(tok, cur` + 1)] ;int nnl = next_non_nl(tok, cur` + 1) /; if (tok`{nnl}.cmp(",") || nnl == max) - ;out.append({tok`{cur`}.data, t, 0, 0}) + ;out.append({tok`{cur`}.data, t, 0, LOCATION.LITERAL}) /; if (tok`{nnl}.cmp(",")) ;cur`++ ;/ |