Difference between revisions of "Code Generation/Exercise 9"

From Wiki**3

< Code Generation
(Variables)
(Function "compute")
Line 94: Line 94:
 
=== Function "compute" ===
 
=== Function "compute" ===
 
<asm>
 
<asm>
 +
;; start of BB1
 +
TEXT
 +
ALIGN
 +
GLOBAL compute, FUNC
 +
LABEL compute
 +
ENTER 4  ; i@-4
 +
ADDRV a
 +
INT 4
 +
MUL
 +
CALL mkvec
 +
;; end of BB1
 +
 +
;; start of BB2
 +
TRASH 4
 +
PUSH
 +
DUP
 +
ADDRA v
 +
TRASH 4
 +
INT 1
 +
LOCA -4
 +
;; end of BB2
 +
 +
;; start of BB3
 +
ALIGN
 +
LABEL fortest
 +
LOCV -4
 +
ADDRV a
 +
LT
 +
JZ forend
 +
;; end of BB3
 +
 +
;; start of BB4
 +
ADDRV v
 +
LOCV -4
 +
INT 8
 +
MUL
 +
ADD
 +
DLOAD
 +
ADDRV v
 +
INT 0
 +
INT 8
 +
MUL
 +
ADD
 +
DLOAD
 +
DCMP
 +
INT 0
 +
GT
 +
JZ ifend2
 +
;; end of BB4
 +
 +
;; start of BB5
 +
INT 3
 +
LOCV -4
 +
MUL
 +
INT 1
 +
SUB
 +
I2D
 +
DDUP
 +
ADDRV v
 +
LOCV -4
 +
INT 8
 +
MUL
 +
ADD
 +
DSTORE
 +
TRASH 8
 +
;; end of BB5
 +
 +
;; start of BB6
 +
ALIGN
 +
LABEL ifend2
 +
ALIGN
 +
LABEL forincr
 +
LOCV -4
 +
DUP
 +
INT 1
 +
ADD
 +
LOCA -4
 +
TRASH 4
 +
JMP fortest
 +
;; end of BB6
 +
 +
;; start of BB7
 +
ALIGN
 +
LABEL forend
 +
ADDRV v
 +
POP
 +
LEAVE
 +
RET
 +
;; end of BB7
  
 
</asm>
 
</asm>

Revision as of 14:27, 27 June 2012

The Original Code

Consider the following C code:

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

Assume that the size of pointers, int, and unsigned long is 32 bits and that the size of double is 64 bits.

Postfix Code

The Postfix code for the above code is as follows: (code has not been thoroughly checked: bug reports are welcome)

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 LOCV 8 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) LOCA -4 LOCV +8 LOCV -4 MUL CALL malloc

end of BB3
start of BB4

TRASH 4 PUSH LOCA -8 LOCV -8 POP LEAVE RET

end of BB4

</asm>

Function "compute"

<asm>

start of BB1

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

end of BB1
start of BB2

TRASH 4 PUSH DUP ADDRA v TRASH 4 INT 1 LOCA -4

end of BB2
start of BB3

ALIGN LABEL fortest LOCV -4 ADDRV a LT JZ forend

end of BB3
start of BB4

ADDRV v LOCV -4 INT 8 MUL ADD DLOAD ADDRV v INT 0 INT 8 MUL ADD DLOAD DCMP INT 0 GT JZ ifend2

end of BB4
start of BB5

INT 3 LOCV -4 MUL INT 1 SUB I2D DDUP ADDRV v LOCV -4 INT 8 MUL ADD DSTORE TRASH 8

end of BB5
start of BB6

ALIGN LABEL ifend2 ALIGN LABEL forincr LOCV -4 DUP INT 1 ADD LOCA -4 TRASH 4 JMP fortest

end of BB6
start of BB7

ALIGN LABEL forend ADDRV v 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