(→Postfix Code) |
(→Postfix Code) |
||
Line 36: | Line 36: | ||
ALIGN | ALIGN | ||
LABEL a | LABEL a | ||
− | + | SINT 10 | |
;; variable "v" | ;; variable "v" | ||
Line 42: | Line 42: | ||
ALIGN | ALIGN | ||
LABEL v | LABEL v | ||
− | + | SINT 0 ; this is a null pointer | |
</asm> | </asm> | ||
}} | }} | ||
Line 60: | Line 60: | ||
ENTER 8 ; s@-4 v@-8 | ENTER 8 ; s@-4 v@-8 | ||
LOCAL 8 | LOCAL 8 | ||
− | + | LDINT | |
INT 1 | INT 1 | ||
LT | LT | ||
Line 68: | Line 68: | ||
;; start of BB2 | ;; start of BB2 | ||
INT 0 | INT 0 | ||
− | + | STFVAL32 | |
LEAVE | LEAVE | ||
RET | RET | ||
Line 78: | Line 78: | ||
INT 8 ; sizeof(double) | INT 8 ; sizeof(double) | ||
LOCAL -4 | LOCAL -4 | ||
− | + | STINT | |
LOCAL +8 | LOCAL +8 | ||
− | + | LDINT | |
LOCAL -4 | LOCAL -4 | ||
− | + | LDINT | |
MUL | MUL | ||
CALL malloc | CALL malloc | ||
Line 89: | Line 89: | ||
;; start of BB4 | ;; start of BB4 | ||
TRASH 4 | TRASH 4 | ||
− | + | LDFVAL32 | |
LOCAL -8 | LOCAL -8 | ||
− | + | STINT | |
LOCAL -8 | LOCAL -8 | ||
− | + | LDINT | |
− | + | STFVAL32 | |
LEAVE | LEAVE | ||
RET | RET | ||
Line 110: | Line 110: | ||
ENTER 4 ; i@-4 | ENTER 4 ; i@-4 | ||
ADDR a | ADDR a | ||
− | + | LDINT | |
INT 4 | INT 4 | ||
MUL | MUL | ||
Line 118: | Line 118: | ||
;; start of BB2 | ;; start of BB2 | ||
TRASH 4 | TRASH 4 | ||
− | + | LDFVAL32 | |
− | + | DUP32 | |
ADDR v | ADDR v | ||
− | + | STINT | |
TRASH 4 | TRASH 4 | ||
INT 1 | INT 1 | ||
LOCAL -4 | LOCAL -4 | ||
− | + | STINT | |
;; end of BB2 | ;; end of BB2 | ||
Line 132: | Line 132: | ||
LABEL fortest | LABEL fortest | ||
LOCAL -4 | LOCAL -4 | ||
− | + | LDINT | |
ADDR a | ADDR a | ||
− | + | LDINT | |
LT | LT | ||
JZ forend | JZ forend | ||
Line 141: | Line 141: | ||
;; start of BB4 | ;; start of BB4 | ||
ADDR v | ADDR v | ||
− | + | LDINT | |
LOCAL -4 | LOCAL -4 | ||
− | + | LDINT | |
INT 8 | INT 8 | ||
MUL | MUL | ||
ADD | ADD | ||
− | + | LDDOUBLE | |
ADDR v | ADDR v | ||
− | + | LDINT | |
INT 0 | INT 0 | ||
INT 8 | INT 8 | ||
MUL | MUL | ||
ADD | ADD | ||
− | + | LDDOUBLE | |
DCMP | DCMP | ||
INT 0 | INT 0 | ||
Line 164: | Line 164: | ||
INT 3 | INT 3 | ||
LOCAL -4 | LOCAL -4 | ||
− | + | LDINT | |
MUL | MUL | ||
INT 1 | INT 1 | ||
SUB | SUB | ||
I2D | I2D | ||
− | + | DUP64 | |
ADDR v | ADDR v | ||
− | + | LDINT | |
LOCAL -4 | LOCAL -4 | ||
− | + | LDINT | |
INT 8 | INT 8 | ||
MUL | MUL | ||
ADD | ADD | ||
− | + | STDOUBLE | |
TRASH 8 | TRASH 8 | ||
;; end of BB5 | ;; end of BB5 | ||
Line 187: | Line 187: | ||
LABEL forincr | LABEL forincr | ||
LOCAL -4 | LOCAL -4 | ||
− | + | LDINT | |
− | + | DUP32 | |
INT 1 | INT 1 | ||
ADD | ADD | ||
LOCAL -4 | LOCAL -4 | ||
− | + | STINT | |
TRASH 4 | TRASH 4 | ||
JMP fortest | JMP fortest | ||
Line 201: | Line 201: | ||
LABEL forend | LABEL forend | ||
ADDR v | ADDR v | ||
− | + | LDINT | |
− | + | STFVAL32 | |
LEAVE | LEAVE | ||
RET | RET |
Consider the following C code and assume that the size of pointers, int, and unsigned long is 32 bits and that the size of double is 64 bits.
<c> static unsigned long a = 10; static double *v; extern void *malloc(unsigned long);
static double *mkvec(unsigned long n) {
if (n < 1) return (double *)0; unsigned long s = sizeof(double); double *v = (double *)malloc(n * s); return v;
}
double *compute() {
v = mkvec(a * 4); for (unsigned long i = 1; i < a; i++) if (v[i] > v[0]) v[i] = 3 * i - 1; return v;
} </c>
The Postfix code for the above code is as follows: (code has not been thoroughly checked: bug reports are welcome)
In the following code sections, BB# means "basic block number".
Static (global) variables |
---|
<asm>
DATA ALIGN LABEL a SINT 10
DATA ; "static" variables are always initialized ALIGN LABEL v SINT 0 ; this is a null pointer </asm> |
Declaration of external function |
---|
<asm> EXTERN malloc </asm> |
Function "mkvec" |
---|
<asm>
TEXT ALIGN LABEL mkvec ENTER 8 ; s@-4 v@-8 LOCAL 8 LDINT INT 1 LT JZ ifend1
INT 0 STFVAL32 LEAVE RET
ALIGN LABEL ifend1 INT 8 ; sizeof(double) LOCAL -4 STINT LOCAL +8 LDINT LOCAL -4 LDINT MUL CALL malloc
TRASH 4 LDFVAL32 LOCAL -8 STINT LOCAL -8 LDINT STFVAL32 LEAVE RET
</asm> |
Function "compute" |
---|
<asm>
TEXT ALIGN GLOBAL compute, FUNC LABEL compute ENTER 4 ; i@-4 ADDR a LDINT INT 4 MUL CALL mkvec
TRASH 4 LDFVAL32 DUP32 ADDR v STINT TRASH 4 INT 1 LOCAL -4 STINT
ALIGN LABEL fortest LOCAL -4 LDINT ADDR a LDINT LT JZ forend
ADDR v LDINT LOCAL -4 LDINT INT 8 MUL ADD LDDOUBLE ADDR v LDINT INT 0 INT 8 MUL ADD LDDOUBLE DCMP INT 0 GT JZ ifend2
INT 3 LOCAL -4 LDINT MUL INT 1 SUB I2D DUP64 ADDR v LDINT LOCAL -4 LDINT INT 8 MUL ADD STDOUBLE TRASH 8
ALIGN LABEL ifend2 ALIGN LABEL forincr LOCAL -4 LDINT DUP32 INT 1 ADD LOCAL -4 STINT TRASH 4 JMP fortest
ALIGN LABEL forend ADDR v LDINT STFVAL32 LEAVE RET
</asm> |
To compile the Postfix code directly, pf2asm can be used (assuming a 32-bit architecture):
pf2asm compute.pf yasm -felf compute.asm