forked from osak/ICFPC2014
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgcc_spec.txt
496 lines (421 loc) · 14.6 KB
/
gcc_spec.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
LDC - load constant
Synopsis: load an immediate literal;
push it onto the data stack
Syntax: LDC $n
Example: LDC 3
Effect:
%s := PUSH(SET_TAG(TAG_INT,$n),%s)
%c := %c+1
LD - load from environment
Synopsis: load a value from the environment;
push it onto the data stack
Syntax: LD $n $i
Example: LD 0 1
Effect:
$fp := %e
while $n > 0 do ; follow chain of frames to get n'th frame
begin
$fp := FRAME_PARENT($fp)
$n := $n-1
end
if FRAME_TAG($fp) == TAG_DUM then FAULT(FRAME_MISMATCH)
$v := FRAME_VALUE($fp, $i) ; i'th element of frame
%s := PUSH($v,%s) ; push onto the data stack
%c := %c+1
Notes:
Values within a frame are indexed from 0.
ADD - integer addition
Synopsis: pop two integers off the data stack;
push their sum
Syntax: ADD
Effect:
$y,%s := POP(%s)
$x,%s := POP(%s)
if TAG($x) != TAG_INT then FAULT(TAG_MISMATCH)
if TAG($y) != TAG_INT then FAULT(TAG_MISMATCH)
$z := $x + $y
%s := PUSH(SET_TAG(TAG_INT,$z),%s)
%c := %c+1
SUB - integer subtraction
Synopsis: pop two integers off the data stack;
push the result of subtracting one from the other
Syntax: SUB
Effect:
$y,%s := POP(%s)
$x,%s := POP(%s)
if TAG($x) != TAG_INT then FAULT(TAG_MISMATCH)
if TAG($y) != TAG_INT then FAULT(TAG_MISMATCH)
$z := $x - $y
%s := PUSH(SET_TAG(TAG_INT,$z),%s)
%c := %c+1
MUL - integer multiplication
Synopsis: pop two integers off the data stack;
push their product
Syntax: MUL
Effect:
$y,%s := POP(%s)
$x,%s := POP(%s)
if TAG($x) != TAG_INT then FAULT(TAG_MISMATCH)
if TAG($y) != TAG_INT then FAULT(TAG_MISMATCH)
$z := $x * $y
%s := PUSH(SET_TAG(TAG_INT,$z),%s)
%c := %c+1
DIV - integer division
Synopsis: pop two integers off the data stack;
push the result of the integer division of one of the other
Syntax: DIV
Effect:
$y,%s := POP(%s)
$x,%s := POP(%s)
if TAG($x) != TAG_INT then FAULT(TAG_MISMATCH)
if TAG($y) != TAG_INT then FAULT(TAG_MISMATCH)
$z := $x / $y
%s := PUSH(SET_TAG(TAG_INT,$z),%s)
%c := %c+1
CEQ - compare equal
Synopsis: pop two integers off the data stack;
test if they are equal;
push the result of the test
Syntax: CEQ
Effect:
$y,%s := POP(%s)
$x,%s := POP(%s)
if TAG($x) != TAG_INT then FAULT(TAG_MISMATCH)
if TAG($y) != TAG_INT then FAULT(TAG_MISMATCH)
if $x == $y then
$z := 1
else
$z := 0
%s := PUSH(SET_TAG(TAG_INT,$z),%s)
%c := %c+1
CGT - compare greater than
Synopsis: pop two integers off the data stack;
test if the first is strictly greater than the second;
push the result of the test
Syntax: CGT
Effect:
$y,%s := POP(%s)
$x,%s := POP(%s)
if TAG($x) != TAG_INT then FAULT(TAG_MISMATCH)
if TAG($y) != TAG_INT then FAULT(TAG_MISMATCH)
if $x > $y then
$z := 1
else
$z := 0
%s := PUSH(SET_TAG(TAG_INT,$z),%s)
%c := %c+1
CGTE - compare greater than or equal
Synopsis: pop two integers off the data stack;
test if the first is greater than or equal to the second;
push the result of the test
Syntax: CGTE
Effect:
$y,%s := POP(%s)
$x,%s := POP(%s)
if TAG($x) != TAG_INT then FAULT(TAG_MISMATCH)
if TAG($y) != TAG_INT then FAULT(TAG_MISMATCH)
if $x >= $y then
$z := 1
else
$z := 0
%s := PUSH(SET_TAG(TAG_INT,$z),%s)
%c := %c+1
ATOM - test if value is an integer
Synopsis: pop a value off the data stack;
test the value tag to see if it is an int;
push the result of the test
Syntax: ATOM
Effect:
$x,%s := POP(%s)
if TAG($x) == TAG_INT then
$y := 1
else
$y := 0
%s := PUSH(SET_TAG(TAG_INT,$y),%s)
%c := %c+1
CONS - allocate a CONS cell
Synopsis: pop two values off the data stack;
allocate a fresh CONS cell;
fill it with the two values;
push the pointer to the CONS cell
Syntax: CONS
Effect:
$y,%s := POP(%s)
$x,%s := POP(%s)
$z := ALLOC_CONS($x,$y)
%s := PUSH(SET_TAG(TAG_CONS,$z),%s)
%c := %c+1
CAR - extract first element from CONS cell
Synopsis: pop a pointer to a CONS cell off the data stack;
extract the first element of the CONS;
push it onto the data stack
Syntax: CAR
Effect:
$x,%s := POP(%s)
if TAG($x) != TAG_CONS then FAULT(TAG_MISMATCH)
$y := CAR($x)
%s := PUSH($y,%s)
%c := %c+1
CDR - extract second element from CONS cell
Synopsis: pop a pointer to a CONS cell off the data stack;
extract the second element of the CONS;
push it onto the data stack
Syntax: CDR
Effect:
$x,%s := POP(%s)
if TAG($x) != TAG_CONS then FAULT(TAG_MISMATCH)
$y := CDR($x)
%s := PUSH($y,%s)
%c := %c+1
SEL - conditional branch
Synopsis: pop an integer off the data stack;
test if it is non-zero;
push the return address to the control stack;
jump to the true address or to the false address
Syntax: SEL $t $f
Example: SEL 335 346 ; absolute instruction addresses
Effect:
$x,%s := POP(%s)
if TAG($x) != TAG_INT then FAULT(TAG_MISMATCH)
%d := PUSH(SET_TAG(TAG_JOIN,%c+1),%d) ; save the return address
if $x == 0 then
%c := $f
else
%c := $t
JOIN - return from branch
Synopsis: pop a return address off the control stack, branch to that address
Syntax: JOIN
Effect:
$x,%d := POP(%d)
if TAG($x) != TAG_JOIN then FAULT(CONTROL_MISMATCH)
%c := $x
LDF - load function
Synopsis: allocate a fresh CLOSURE cell;
fill it with the literal code address and the current
environment frame pointer;
push the pointer to the CLOSURE cell onto the data stack
Syntax: LDF $f
Example: LDF 634 ; absolute instruction addresses
Effect:
$x := ALLOC_CLOSURE($f,%e)
%s := PUSH(SET_TAG(TAG_CLOSURE,$x),%s)
%c := %c+1
AP - call function
Synopsis: pop a pointer to a CLOSURE cell off the data stack;
allocate an environment frame of size $n;
set the frame's parent to be the environment frame pointer
from the CLOSURE cell;
fill the frame's body with $n values from the data stack;
save the environment pointer and return address
to the control stack;
set the current environment frame pointer to the new frame;
jump to the code address from the CLOSURE cell;
Syntax: AP $n
Example: AP 3 ; number of arguments to copy
Effect:
$x,%s := POP(%s) ; get and examine function closure
if TAG($x) != TAG_CLOSURE then FAULT(TAG_MISMATCH)
$f := CAR_CLOSURE($x)
$e := CDR_CLOSURE($x)
$fp := ALLOC_FRAME($n) ; create a new frame for the call
FRAME_PARENT($fp) := $e
$i := $n-1
while $i != -1 do ; copy n values from the stack into the frame in reverse order
begin
$y,%s := POP(%s)
FRAME_VALUE($fp,$i) := $y
$i := $i-1
end
%d := PUSH(%e,%d) ; save frame pointer
%d := PUSH(SET_TAG(TAG_RET,%c+1),%d) ; save return address
%e := $fp ; establish new environment
%c := $f ; jump to function
RTN - return from function call
Synopsis: pop a stack pointer, return address and environment frame
pointer off of the control stack;
restore the stack and environment;
jump to the return address
Syntax: RTN
Effect:
$x,%d := POP(%d) ; pop return address
if TAG($x) == TAG_STOP then MACHINE_STOP
if TAG($x) != TAG_RET then FAULT(CONTROL_MISMATCH)
$y,%d := POP(%d) ; pop frame pointer
%e := $y ; restore environment
%c := $x ; jump to return address
Notes:
Standard ABI convention is to leave the function return value on the
top of the data stack. Multiple return values on the stack is possible,
but not used in the standard ABI.
The latest hardware revision optimizes the deallocation of the
environment frame. If the environment has not been captured by LDF
(directly or indirectly) then it can be immediately deallocated.
Otherwise it is left for GC.
DUM - create empty environment frame
Synopsis: Prepare an empty frame;
push it onto the environment chain;
Syntax: DUM $n
Example: DUM 3 ; size of frame to allocate
Effect:
$fp := ALLOC_FRAME($n) ; create a new empty frame of size $n
FRAME_PARENT($fp) := %e ; set its parent frame
FRAME_TAG($fp) := TAG_DUM ; mark the frame as dummy
%e := $fp ; set it as the new environment frame
%c := %c+1
Notes:
To be used with RAP to fill in the frame body.
RAP - recursive environment call function
Synopsis: pop a pointer to a CLOSURE cell off the data stack;
the current environment frame pointer must point to an empty
frame of size $n;
fill the empty frame's body with $n values from the data stack;
save the parent pointer of the current environment frame
and return address to the control stack;
set the current environment frame pointer to the environment
frame pointer from the CLOSURE cell;
jump to the code address from the CLOSURE cell;
Syntax: RAP $n
Example: RAP 3 ; number of arguments to copy
Effect:
$x,%s := POP(%s) ; get and examine function closure
if TAG($x) != TAG_CLOSURE then FAULT(TAG_MISMATCH)
$f := CAR_CLOSURE($x)
$fp := CDR_CLOSURE($x)
if FRAME_TAG(%e) != TAG_DUM then FAULT(FRAME_MISMATCH)
if FRAME_SIZE(%e) != $n then FAULT(FRAME_MISMATCH)
if %e != $fp then FAULT(FRAME_MISMATCH)
$i := $n-1
while $i != -1 do ; copy n values from the stack into the empty frame in reverse order
begin
$y,%s := POP(%s)
FRAME_VALUE($fp,$i) := $y
$i := $i-1
end
$ep := FRAME_PARENT(%e)
%d := PUSH($ep,%d) ; save frame pointer
%d := PUSH(SET_TAG(TAG_RET,%c+1),%d) ; save return address
FRAME_TAG($fp) := !TAG_DUM ; mark the frame as normal
%e := $fp ; establish new environment
%c := $f ; jump to function
STOP - terminate co-processor execution
Synopsis: terminate co-processor execution and signal the main proessor.
Syntax: STOP
Effect:
MACHINE_STOP
Notes:
This instruction is no longer part of the standard ABI. The standard ABI
calling convention is to use a TAG_STOP control stack entry. See RTN.
TSEL - tail-call conditional branch
Synopsis: pop an integer off the data stack;
test if it is non-zero;
jump to the true address or to the false address
Syntax: TSEL $t $f
Example: TSEL 335 346 ; absolute instruction addresses
Effect:
$x,%s := POP(%s)
if TAG($x) != TAG_INT then FAULT(TAG_MISMATCH)
if $x == 0 then
%c := $f
else
%c := $t
Notes:
This instruction is the same as SEL but it does not push a return address
TAP - tail-call function
Synopsis: pop a pointer to a CLOSURE cell off the data stack;
allocate an environment frame of size $n;
set the frame's parent to be the environment frame pointer
from the CLOSURE cell;
fill the frame's body with $n values from the data stack;
set the current environment frame pointer to the new frame;
jump to the code address from the CLOSURE cell;
Syntax: TAP $n
Example: TAP 3 ; number of arguments to copy
Effect:
$x,%s := POP(%s) ; get and examine function closure
if TAG($x) != TAG_CLOSURE then FAULT(TAG_MISMATCH)
$f := CAR_CLOSURE($x)
$e := CDR_CLOSURE($x)
$fp := ALLOC_FRAME($n) ; create a new frame for the call
FRAME_PARENT($fp) := $e
$i := $n-1
while $i != -1 do ; copy n values from the stack into the frame in reverse order
begin
$y,%s := POP(%s)
FRAME_VALUE($fp,$i) := $y
$i := $i-1
end
%e := $fp ; establish new environment
%c := $f ; jump to function
Notes:
This instruction is the same as AP but it does not push a return address
The latest hardware revision optimizes the case where the environment
frame has not been captured by LDF and the number of args $n in the
call fit within the current frame. In this case it will overwrite the
frame rather than allocating a fresh one.
TRAP - recursive environment tail-call function
Synopsis: pop a pointer to a CLOSURE cell off the data stack;
the current environment frame pointer must point to an empty
frame of size $n;
fill the empty frame's body with $n values from the data stack;
set the current environment frame pointer to the environment
frame pointer from the CLOSURE cell;
jump to the code address from the CLOSURE cell;
Syntax: TRAP $n
Example: TRAP 3 ; number of arguments to copy
Effect:
$x,%s := POP(%s) ; get and examine function closure
if TAG($x) != TAG_CLOSURE then FAULT(TAG_MISMATCH)
$f := CAR_CLOSURE($x)
$fp := CDR_CLOSURE($x)
if FRAME_TAG(%e) != TAG_DUM then FAULT(FRAME_MISMATCH)
if FRAME_SIZE(%e) != $n then FAULT(FRAME_MISMATCH)
if %e != $fp then FAULT(FRAME_MISMATCH)
$i := $n-1
while $i != -1 do ; copy n values from the stack into the empty frame in reverse order
begin
$y,%s := POP(%s)
FRAME_VALUE($fp,$i) := $y
$i := $i-1
end
FRAME_TAG($fp) := !TAG_DUM
%e := $fp ; establish new environment
%c := $f ; jump to function
Notes:
This instruction is the same as RAP but it does not push a return address
ST - store to environment
Synopsis: pop a value from the data stack and store to the environment
Syntax: ST $n $i
Example: ST 0 1
Effect:
$fp := %e
while $n > 0 do ; follow chain of frames to get n'th frame
begin
$fp := FRAME_PARENT($fp)
$n := $n-1
end
if FRAME_TAG($fp) == TAG_DUM then FAULT(FRAME_MISMATCH)
$v,%s := POP(%s) ; pop value from the data stack
FRAME_VALUE($fp, $i) := $v ; modify i'th element of frame
%c := %c+1
DBUG - printf debugging
Synopsis: If tracing is enabled, suspend execution and raise a trace
interrupt on the main processor. The main processor will read
the value and resume co-processor execution. On resumption
the value will be popped from the data stack. If tracing is not
enabled the value is popped from the data stack and discarded.
Syntax: DBUG
Effect:
$x,%s := POP(%s)
%c := %c+1
Notes:
This is the formal effect on the state of the machine. It does
also raise an interrupt but this has no effect on the machine state.
BRK - breakpoint debugging
Synopsis: If breakpoint debugging is enabled, suspend execution and raise
a breakpoint interrupt on the main processor. The main processor
may inspect the state of the co-processor and can resume
execution. If breakpoint debugging is not enabled it has no
effect.
Syntax: BRK
Effect:
%c := %c+1