summaryrefslogtreecommitdiff
path: root/emit.fun
diff options
context:
space:
mode:
authorVladimir Azarov <avm@intermediate-node.net>2025-08-11 16:23:42 +0200
committerVladimir Azarov <avm@intermediate-node.net>2025-08-11 16:23:42 +0200
commit47ce22ee86ad9fb329585e7d9ae2052772248c95 (patch)
treedb983bdf1f48338f87603249db4b93fa5d846653 /emit.fun
parent69cf1be454c7caae026107e645c5343365b1be19 (diff)
IrJmpc
Diffstat (limited to 'emit.fun')
-rw-r--r--emit.fun71
1 files changed, 46 insertions, 25 deletions
diff --git a/emit.fun b/emit.fun
index 215c335..6b8ceb2 100644
--- a/emit.fun
+++ b/emit.fun
@@ -125,6 +125,7 @@ functor Emit(I: IL) = struct
fun emitAggrLayout id =
let
val (_, size, layout) = D.get P.iniLayouts id
+ val size = I.wrapTo8 size
val () = fprint `"\n" %
@@ -212,7 +213,7 @@ functor Emit(I: IL) = struct
val parts = collectStr symbols []
in
- fprint `".S" I id `":\t" %;
+ fprint `"S." I id `":\t" %;
fprint `"db " %;
List.app (fn p => fprint A1 printPart p `", " %) parts;
fprint `"0\n" %
@@ -227,7 +228,7 @@ functor Emit(I: IL) = struct
fun f (_, (true, _, _)) = ()
| f (n, (false, _, _)) = (
fprint `"\talign 16\n" %;
- fprint `".I" I n `":" %;
+ fprint `"I." I n `":" %;
emitAggrLayout n
)
in
@@ -378,7 +379,7 @@ functor Emit(I: IL) = struct
| I.IrExtZero _ | I.IrExtSign _
| I.IrLoad _ | I.IrStore _ | I.IrJmp _
- | I.IrJz _ | I.IrJnz _ | I.IrNopLabel _
+ | I.IrJz _ | I.IrJnz _ | I.IrJmpc _ | I.IrNopLabel _
| I.IrNop _ | I.IrRet _ | I.IrAlloc _
| I.IrCopy _ => IaNone
| I.IrFcall (_, _, args) => fcallAff args
@@ -1121,7 +1122,7 @@ functor Emit(I: IL) = struct
val repr = PP.?? id
val repr =
if String.sub (repr, 0) = #"\"" then
- ".S" ^ Int.toString id
+ "S." ^ Int.toString id
else
repr
in
@@ -1175,6 +1176,7 @@ functor Emit(I: IL) = struct
xorIdiom r
else
sprintf `"mov " A2 pr is8 r `", " A2 pc is8 c %
+
fun movMV is8 off c =
let
val () = if not $ fitsInNsx 32 c then raise Unreachable else ()
@@ -1676,9 +1678,21 @@ functor Emit(I: IL) = struct
pre @ mid @ main
end
- fun emitCmp E (cmpop, rd, rs1, rs2) =
+ fun cmpOp2cc op' =
+ case op' of
+ I.Cmpeq => "e"
+ | I.Cmpneq => "ne"
+ | I.Cmpul => "b"
+ | I.Cmpug => "a"
+ | I.Cmpule => "be"
+ | I.Cmpuge => "ae"
+ | I.Cmpsl => "l"
+ | I.Cmpsg => "g"
+ | I.Cmpsle => "le"
+ | I.Cmpsge => "ge"
+
+ fun getCmpSeq E rs1 rs2 =
let
- val (_, td) = getType E rd
val (is82, ts1) = getType E rs1
val (is83, ts2) = getType E rs2
@@ -1692,8 +1706,6 @@ functor Emit(I: IL) = struct
fun RwithRM r vt = sprintf `"cmp " A2 pr is82 r `", " A2 prm is82 vt %
- val zeroing = sprintf `"xor " A2 pr false Rax `", " A2 pr false Rax %
-
val (pre, main) =
case (ts1, ts2) of
(VtReg _ | VtStack _, VtConst c) =>
@@ -1708,22 +1720,25 @@ functor Emit(I: IL) = struct
| (VtStack off, VtStack _) => ([movRM is82 Rax off], RwithRM Rax ts2)
| (VtUnk, _) | (_, VtUnk) => raise Unreachable
- val flags =
- case cmpop of
- I.Cmpeq => "e"
- | I.Cmpneq => "ne"
- | I.Cmpul => "b"
- | I.Cmpug => "a"
- | I.Cmpule => "be"
- | I.Cmpuge => "ae"
- | I.Cmpsl => "l"
- | I.Cmpsg => "g"
- | I.Cmpsle => "le"
- | I.Cmpsge => "ge"
+ in
+ pre @ [main]
+ end
- val setPart = sprintf `"set" `flags `" al" %
+ fun emitCmp E (op', rd, rs1, rs2) =
+ let
+ val (_, td) = getType E rd
+ val cmpPart = getCmpSeq E rs1 rs2
+ val setPart = sprintf `"set" `(cmpOp2cc op') `" dl" %
+ in
+ [xorIdiom Rdx] @ cmpPart @ [setPart] @ [mov true td (VtReg Rdx)]
+ end
+
+ fun emitJmpc E (op', rs1, rs2, lid) =
+ let
+ val cmpPart = getCmpSeq E rs1 rs2
+ val jmp = sprintf `"j" `(cmpOp2cc op') `" " I.Pl lid %
in
- [zeroing] @ pre @ [main] @ [setPart] @ [mov true td (VtReg Rax)]
+ cmpPart @ [jmp]
end
fun emitExt E (vd, vs, from) op' =
@@ -1742,7 +1757,12 @@ functor Emit(I: IL) = struct
val main =
case (to, from) of
(I.AC4, I.AC1) | (I.AC4, I.AC2) => ext ()
- | (I.AC8, I.AC1) | (I.AC8, I.AC2) | (I.AC8, I.AC4) => ext ()
+ | (I.AC8, I.AC1) | (I.AC8, I.AC2) => ext ()
+ | (I.AC8, I.AC4) =>
+ if op' = "movzx" then
+ mov false (VtReg dest) ts
+ else
+ ext ()
| (I.AC4, I.AC4) | (I.AC4, I.AC8) => raise Unreachable
| (I.AC8, I.AC8) => raise Unreachable
@@ -1814,7 +1834,7 @@ functor Emit(I: IL) = struct
in
case t1 of
VtReg r =>
- [ sprintf `"lea " A2 pr true r `", [rsp-" I stackOffset `"]" % ]
+ [ sprintf `"lea " A2 pr true r `", [rbp-" I stackOffset `"]" % ]
| _ => raise Unreachable
end
| emitAlloc _ (_, _, NONE) = raise Unreachable
@@ -1858,7 +1878,7 @@ functor Emit(I: IL) = struct
rev acc
else
let
- val from = sprintf `"mov rax, qword [.I" I lid `"+" W off `"]" %
+ val from = sprintf `"mov rax, qword [I." I lid `"+" W off `"]" %
val to =
sprintf `"mov [" A2 pr true destReg `"+" W off `"], rax" %
in
@@ -1990,6 +2010,7 @@ functor Emit(I: IL) = struct
| I.IrIMod t => emitDivMod E t "idiv" Rdx true
| I.IrCmp q => emitCmp E q
+ | I.IrJmpc q => emitJmpc E q
| I.IrLoad t => emitLoad E t
| I.IrStore t => emitStore E t