Skip to content

Commit a0ec37e

Browse files
committed
Add conditional move instructions.
1 parent 1f7691a commit a0ec37e

3 files changed

Lines changed: 328 additions & 0 deletions

File tree

langs/a86/ast.rkt

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,14 @@
2929
(error n "expects symbol; given ~v" x))
3030
x))
3131

32+
(define check:cmov
33+
(λ (a1 a2 n)
34+
(unless (register? a1)
35+
(error n "expects register; given ~v" a1))
36+
(unless (or (register? a2) (offset? a2))
37+
(error n "expects register or offset; given ~v" a2))
38+
(values a1 a2)))
39+
3240
(define check:arith
3341
(λ (a1 a2 n)
3442
(unless (register? a1)
@@ -141,6 +149,16 @@
141149
(instruct Jno (x) check:target)
142150
(instruct Jc (x) check:target)
143151
(instruct Jnc (x) check:target)
152+
(instruct Cmove (dst src) check:cmov)
153+
(instruct Cmovne (dst src) check:cmov)
154+
(instruct Cmovl (dst src) check:cmov)
155+
(instruct Cmovle (dst src) check:cmov)
156+
(instruct Cmovg (dst src) check:cmov)
157+
(instruct Cmovge (dst src) check:cmov)
158+
(instruct Cmovo (dst src) check:cmov)
159+
(instruct Cmovno (dst src) check:cmov)
160+
(instruct Cmovc (dst src) check:cmov)
161+
(instruct Cmovnc (dst src) check:cmov)
144162
(instruct And (dst src) check:src-dest)
145163
(instruct Or (dst src) check:src-dest)
146164
(instruct Xor (dst src) check:src-dest)
@@ -210,6 +228,16 @@
210228
(Jno? x)
211229
(Jc? x)
212230
(Jnc? x)
231+
(Cmove? x)
232+
(Cmovne? x)
233+
(Cmovl? x)
234+
(Cmovle? x)
235+
(Cmovg? x)
236+
(Cmovge? x)
237+
(Cmovo? x)
238+
(Cmovno? x)
239+
(Cmovc? x)
240+
(Cmovnc? x)
213241
(And? x)
214242
(Or? x)
215243
(Xor? x)

langs/a86/printer.rkt

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,46 @@
153153
[(Jnc l)
154154
(string-append tab "jnc "
155155
(jump-target->string l))]
156+
[(Cmove dst src)
157+
(string-append tab "cmove "
158+
(reg->string dst) ", "
159+
(arg->string src))]
160+
[(Cmovne dst src)
161+
(string-append tab "cmovne "
162+
(reg->string dst) ", "
163+
(arg->string src))]
164+
[(Cmovl dst src)
165+
(string-append tab "cmovl "
166+
(reg->string dst) ", "
167+
(arg->string src))]
168+
[(Cmovle dst src)
169+
(string-append tab "cmovle "
170+
(reg->string dst) ", "
171+
(arg->string src))]
172+
[(Cmovg dst src)
173+
(string-append tab "cmovg "
174+
(reg->string dst) ", "
175+
(arg->string src))]
176+
[(Cmovge dst src)
177+
(string-append tab "cmovge "
178+
(reg->string dst) ", "
179+
(arg->string src))]
180+
[(Cmovo dst src)
181+
(string-append tab "cmovo "
182+
(reg->string dst) ", "
183+
(arg->string src))]
184+
[(Cmovno dst src)
185+
(string-append tab "cmovno "
186+
(reg->string dst) ", "
187+
(arg->string src))]
188+
[(Cmovc dst src)
189+
(string-append tab "cmovc "
190+
(reg->string dst) ", "
191+
(arg->string src))]
192+
[(Cmovnc dst src)
193+
(string-append tab "cmovnc "
194+
(reg->string dst) ", "
195+
(arg->string src))]
156196
[(Call l)
157197
(string-append tab "call "
158198
(jump-target->string l))]

www/notes/a86.scrbl

Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1096,6 +1096,266 @@ Each register plays the same role as in x86, so for example
10961096
]
10971097
}
10981098

1099+
@defstruct*[Cmove ([dst register?] [src (or/c register? offset?)])]{
1100+
Move from @racket[dst] to @racket[src] if the comparison flag is set to equal.
1101+
1102+
@ex[
1103+
(asm-interp
1104+
(prog
1105+
(Global 'entry)
1106+
(Label 'entry)
1107+
(Mov 'rax 0)
1108+
(Cmp 'rax 0)
1109+
(Mov 'r9 1)
1110+
(Cmove 'rax 'r9)
1111+
(Ret)))
1112+
1113+
(asm-interp
1114+
(prog
1115+
(Global 'entry)
1116+
(Label 'entry)
1117+
(Mov 'rax 2)
1118+
(Cmp 'rax 0)
1119+
(Mov 'r9 1)
1120+
(Cmove 'rax 'r9)
1121+
(Ret)))
1122+
]
1123+
}
1124+
1125+
@defstruct*[Cmovne ([dst register?] [src (or/c register? offset?)])]{
1126+
Move from @racket[dst] to @racket[src] if the comparison flag is set to not equal.
1127+
1128+
@ex[
1129+
(asm-interp
1130+
(prog
1131+
(Global 'entry)
1132+
(Label 'entry)
1133+
(Mov 'rax 0)
1134+
(Cmp 'rax 0)
1135+
(Mov 'r9 1)
1136+
(Cmovne 'rax 'r9)
1137+
(Ret)))
1138+
1139+
(asm-interp
1140+
(prog
1141+
(Global 'entry)
1142+
(Label 'entry)
1143+
(Mov 'rax 2)
1144+
(Cmp 'rax 0)
1145+
(Mov 'r9 1)
1146+
(Cmovne 'rax 'r9)
1147+
(Ret)))
1148+
]
1149+
}
1150+
1151+
@defstruct*[Cmovl ([dst register?] [src (or/c register? offset?)])]{
1152+
Move from @racket[dst] to @racket[src] if the comparison flag is set to less than.
1153+
1154+
@ex[
1155+
(asm-interp
1156+
(prog
1157+
(Global 'entry)
1158+
(Label 'entry)
1159+
(Mov 'rax 0)
1160+
(Cmp 'rax 0)
1161+
(Mov 'r9 1)
1162+
(Cmovl 'rax 'r9)
1163+
(Ret)))
1164+
1165+
(asm-interp
1166+
(prog
1167+
(Global 'entry)
1168+
(Label 'entry)
1169+
(Mov 'rax -1)
1170+
(Cmp 'rax 0)
1171+
(Mov 'r9 1)
1172+
(Cmovl 'rax 'r9)
1173+
(Ret)))
1174+
]
1175+
}
1176+
1177+
@defstruct*[Cmovle ([dst register?] [src (or/c register? offset?)])]{
1178+
Move from @racket[dst] to @racket[src] if the comparison flag is set to less than or equal.
1179+
1180+
@ex[
1181+
(asm-interp
1182+
(prog
1183+
(Global 'entry)
1184+
(Label 'entry)
1185+
(Mov 'rax 0)
1186+
(Cmp 'rax 0)
1187+
(Mov 'r9 1)
1188+
(Cmovle 'rax 'r9)
1189+
(Ret)))
1190+
1191+
(asm-interp
1192+
(prog
1193+
(Global 'entry)
1194+
(Label 'entry)
1195+
(Mov 'rax 2)
1196+
(Cmp 'rax 0)
1197+
(Mov 'r9 1)
1198+
(Cmovle 'rax 'r9)
1199+
(Ret)))
1200+
]
1201+
}
1202+
1203+
@defstruct*[Cmovg ([dst register?] [src (or/c register? offset?)])]{
1204+
Move from @racket[dst] to @racket[src] if the comparison flag is set to greather than.
1205+
1206+
@ex[
1207+
(asm-interp
1208+
(prog
1209+
(Global 'entry)
1210+
(Label 'entry)
1211+
(Mov 'rax 0)
1212+
(Cmp 'rax 0)
1213+
(Mov 'r9 1)
1214+
(Cmovg 'rax 'r9)
1215+
(Ret)))
1216+
1217+
(asm-interp
1218+
(prog
1219+
(Global 'entry)
1220+
(Label 'entry)
1221+
(Mov 'rax 2)
1222+
(Cmp 'rax 0)
1223+
(Mov 'r9 1)
1224+
(Cmovg 'rax 'r9)
1225+
(Ret)))
1226+
]
1227+
}
1228+
1229+
@defstruct*[Cmovge ([dst register?] [src (or/c register? offset?)])]{
1230+
Move from @racket[dst] to @racket[src] if the comparison flag is set to greater than or equal.
1231+
1232+
@ex[
1233+
(asm-interp
1234+
(prog
1235+
(Global 'entry)
1236+
(Label 'entry)
1237+
(Mov 'rax -1)
1238+
(Cmp 'rax 0)
1239+
(Mov 'r9 1)
1240+
(Cmovge 'rax 'r9)
1241+
(Ret)))
1242+
1243+
(asm-interp
1244+
(prog
1245+
(Global 'entry)
1246+
(Label 'entry)
1247+
(Mov 'rax 2)
1248+
(Cmp 'rax 0)
1249+
(Mov 'r9 1)
1250+
(Cmovge 'rax 'r9)
1251+
(Ret)))
1252+
]
1253+
}
1254+
1255+
@defstruct*[Cmovo ([dst register?] [src (or/c register? offset?)])]{
1256+
Move from @racket[dst] to @racket[src] if the overflow flag is set.
1257+
1258+
@ex[
1259+
(asm-interp
1260+
(prog
1261+
(Global 'entry)
1262+
(Label 'entry)
1263+
(Mov 'rax (- (expt 2 63) 1))
1264+
(Add 'rax 1)
1265+
(Mov 'r9 1)
1266+
(Cmovo 'rax 'r9)
1267+
(Ret)))
1268+
1269+
(asm-interp
1270+
(prog
1271+
(Global 'entry)
1272+
(Label 'entry)
1273+
(Mov 'rax (- (expt 2 63) 2))
1274+
(Add 'rax 1)
1275+
(Mov 'r9 1)
1276+
(Cmovo 'rax 'r9)
1277+
(Ret)))
1278+
]
1279+
}
1280+
1281+
@defstruct*[Cmovno ([dst register?] [src (or/c register? offset?)])]{
1282+
Move from @racket[dst] to @racket[src] if the overflow flag is not set.
1283+
1284+
@ex[
1285+
(asm-interp
1286+
(prog
1287+
(Global 'entry)
1288+
(Label 'entry)
1289+
(Mov 'rax (- (expt 2 63) 1))
1290+
(Add 'rax 1)
1291+
(Mov 'r9 1)
1292+
(Cmovno 'rax 'r9)
1293+
(Ret)))
1294+
1295+
(asm-interp
1296+
(prog
1297+
(Global 'entry)
1298+
(Label 'entry)
1299+
(Mov 'rax (- (expt 2 63) 2))
1300+
(Add 'rax 1)
1301+
(Mov 'r9 1)
1302+
(Cmovno 'rax 'r9)
1303+
(Ret)))
1304+
]
1305+
}
1306+
1307+
@defstruct*[Cmovc ([dst register?] [src (or/c register? offset?)])]{
1308+
Move from @racket[dst] to @racket[src] if the carry flag is set.
1309+
1310+
@ex[
1311+
(asm-interp
1312+
(prog
1313+
(Global 'entry)
1314+
(Label 'entry)
1315+
(Mov 'rax (- (expt 2 64) 1))
1316+
(Add 'rax 1)
1317+
(Mov 'r9 1)
1318+
(Cmovc 'rax 'r9)
1319+
(Ret)))
1320+
1321+
(asm-interp
1322+
(prog
1323+
(Global 'entry)
1324+
(Label 'entry)
1325+
(Mov 'rax (- (expt 2 64) 2))
1326+
(Add 'rax 1)
1327+
(Mov 'r9 1)
1328+
(Cmovc 'rax 'r9)
1329+
(Ret)))
1330+
]
1331+
}
1332+
1333+
@defstruct*[Cmovnc ([dst register?] [src (or/c register? offset?)])]{
1334+
Move from @racket[dst] to @racket[src] if the carry flag is not set.
1335+
1336+
@ex[
1337+
(asm-interp
1338+
(prog
1339+
(Global 'entry)
1340+
(Label 'entry)
1341+
(Mov 'rax (- (expt 2 64) 1))
1342+
(Add 'rax 1)
1343+
(Mov 'r9 1)
1344+
(Cmovnc 'rax 'r9)
1345+
(Ret)))
1346+
1347+
(asm-interp
1348+
(prog
1349+
(Global 'entry)
1350+
(Label 'entry)
1351+
(Mov 'rax (- (expt 2 64) 2))
1352+
(Add 'rax 1)
1353+
(Mov 'r9 1)
1354+
(Cmovnc 'rax 'r9)
1355+
(Ret)))
1356+
]
1357+
}
1358+
10991359

11001360
@defstruct*[And ([dst (or/c register? offset?)] [src (or/c register? offset? exact-integer?)])]{
11011361
Compute logical ``and'' of @racket[dst] and @racket[src] and put result in @racket[dst].

0 commit comments

Comments
 (0)