Difference between revisions of "Code Generation/Exercise 9"

From Wiki**3

< Code Generation
(Function "mkvec")
(Function "compute")
Line 109: Line 109:
 
LABEL compute
 
LABEL compute
 
ENTER 4  ; i@-4
 
ENTER 4  ; i@-4
ADDRV a
+
ADDR a
 +
LOAD
 
INT 4
 
INT 4
 
MUL
 
MUL
Line 119: Line 120:
 
PUSH
 
PUSH
 
DUP
 
DUP
ADDRA v
+
ADDR v
 +
STORE
 
TRASH 4
 
TRASH 4
 
INT 1
 
INT 1
LOCA -4
+
LOCAL -4
 +
STORE
 
;; end of BB2
 
;; end of BB2
  
Line 128: Line 131:
 
ALIGN
 
ALIGN
 
LABEL fortest
 
LABEL fortest
LOCV -4
+
LOCAL -4
ADDRV a
+
LOAD
 +
ADDR a
 +
LOAD
 
LT
 
LT
 
JZ forend
 
JZ forend
Line 135: Line 140:
  
 
;; start of BB4
 
;; start of BB4
ADDRV v
+
ADDR v
LOCV -4
+
LOAD
 +
LOCAL -4
 +
LOAD
 
INT 8
 
INT 8
 
MUL
 
MUL
 
ADD
 
ADD
 
DLOAD
 
DLOAD
ADDRV v
+
ADDR v
 +
LOAD
 
INT 0
 
INT 0
 
INT 8
 
INT 8
Line 155: Line 163:
 
;; start of BB5
 
;; start of BB5
 
INT 3
 
INT 3
LOCV -4
+
LOCAL -4
 +
LOAD
 
MUL
 
MUL
 
INT 1
 
INT 1
Line 161: Line 170:
 
I2D
 
I2D
 
DDUP
 
DDUP
ADDRV v
+
ADDR v
LOCV -4
+
LOAD
 +
LOCAL -4
 +
LOAD
 
INT 8
 
INT 8
 
MUL
 
MUL
Line 175: Line 186:
 
ALIGN
 
ALIGN
 
LABEL forincr
 
LABEL forincr
LOCV -4
+
LOCAL -4
 +
LOAD
 
DUP
 
DUP
 
INT 1
 
INT 1
 
ADD
 
ADD
LOCA -4
+
LOCAL -4
 +
STORE
 
TRASH 4
 
TRASH 4
 
JMP fortest
 
JMP fortest
Line 187: Line 200:
 
ALIGN
 
ALIGN
 
LABEL forend
 
LABEL forend
ADDRV v
+
ADDR v
 +
LOAD
 
POP
 
POP
 
LEAVE
 
LEAVE

Revision as of 08:20, 9 May 2017

The Original Code

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>

Postfix Code

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".

Variables

<asm>

variable "a"

DATA ALIGN LABEL a CONST 10

variable "v"

DATA  ; "static" variables are always initialized ALIGN LABEL v CONST 0  ; this is a null pointer </asm>

Declaration of external function

<asm> EXTERN malloc </asm>

Function "mkvec"

<asm>

start of BB1

TEXT ALIGN LABEL mkvec ENTER 8  ; s@-4 v@-8 LOCAL 8 LOAD INT 1 LT JZ ifend1

end of BB1
start of BB2

INT 0 POP LEAVE RET

end of BB2
start of BB3

ALIGN LABEL ifend1 INT 8  ; sizeof(double) LOCAL -4 STORE LOCAL +8 LOAD LOCAL -4 LOAD MUL CALL malloc

end of BB3
start of BB4

TRASH 4 PUSH LOCAL -8 STORE LOCAL -8 LOAD POP LEAVE RET

end of BB4

</asm>

Function "compute"

<asm>

start of BB1

TEXT ALIGN GLOBAL compute, FUNC LABEL compute ENTER 4  ; i@-4 ADDR a LOAD INT 4 MUL CALL mkvec

end of BB1
start of BB2

TRASH 4 PUSH DUP ADDR v STORE TRASH 4 INT 1 LOCAL -4 STORE

end of BB2
start of BB3

ALIGN LABEL fortest LOCAL -4 LOAD ADDR a LOAD LT JZ forend

end of BB3
start of BB4

ADDR v LOAD LOCAL -4 LOAD INT 8 MUL ADD DLOAD ADDR v LOAD INT 0 INT 8 MUL ADD DLOAD DCMP INT 0 GT JZ ifend2

end of BB4
start of BB5

INT 3 LOCAL -4 LOAD MUL INT 1 SUB I2D DDUP ADDR v LOAD LOCAL -4 LOAD INT 8 MUL ADD DSTORE TRASH 8

end of BB5
start of BB6

ALIGN LABEL ifend2 ALIGN LABEL forincr LOCAL -4 LOAD DUP INT 1 ADD LOCAL -4 STORE TRASH 4 JMP fortest

end of BB6
start of BB7

ALIGN LABEL forend ADDR v LOAD POP LEAVE RET

end of BB7

</asm>

Compiling and Running

To compile the Postfix code directly, pf2asm can be used (assuming a 32-bit architecture):

pf2asm compute.pf
yasm -felf compute.asm