Code Generation/Exercise 7

From Wiki**3

< Code Generation

The Original Code

Consider the following C function:

int *traverse(int vec[], int lim) {
  int *ptr = vec + lim - 1, ix = lim - 2;
  while (ix >= 0) {
    ptr = (vec[ix] > *ptr) ? vec + ix : ptr;
    ix--;
  }
  return ptr;
}

Postfix Code

The Postfix code for the above function is as follows:

Postfix code
TEXT
ALIGN
GLOBL traverse, FUNC
LABEL traverse
ENTER 8  ; ptr@-4 ix@-8 vec@+8 lim@+12

; init prt (not assignment)
LOCAL +8
LDINT  ; vec
LOCAL +12
LDINT ; lim
INT 4    ; sizeof int
MUL
ADD      ; vec + lim
INT 1
INT 4    ; sizeof int
MUL
SUB      ; vec + lim - 1
LOCAL -4
STINT  ; ptr = vec + lim - 1

; init ix (not assignment)
LOCAL +12
LDINT ; lim
INT 2
SUB
LOCAL -8
STINT  ; ix = lim -2

; while start: test
ALIGN
LABEL while_test
LOCAL -8
LDINT
INT 0
GE       ; ix >= 0
JZ while_end

; while block

; ?: operator
LOCAL +8
LDINT  ; vec
LOCAL -8
LDINT  ; ix
INT 4    ; sizeof int
MUL
ADD      ; vec + ix
LDINT     ; *(vec+ix) --> vec[ix]

LOCAL -4
LDINT  ; ptr
LDINT  ; *ptr

GT
JZ three_false_part

; ?: true part
LOCAL +8
LDINT  ; vec
LOCAL -8
LDINT  ; ix
INT 4    ; sizeof int
MUL
ADD      ; vec + ix

JMP three_end

; ?: false part
ALIGN
LABEL three_false_part

LOCAL -4
LDINT  ; ptr

; ?: end
ALIGN
LABEL three_end

DUP32      ; for assignment
LOCAL -4
STINT  ; ptr = ?: ...

; trash expression value (used as instruction)
TRASH 4

; decrement ix
LOCAL -8
LDINT  ; ix
DUP32
INT 1
SUB
LOCAL -8
STINT  ; ix = ix - 1
TRASH 4  ; (ix-- used as instruction)

; end while block
JMP while_test

; exit while cycle
ALIGN
LABEL while_end

; return ptr
LOCAL -4
LDINT
STFVAL32
LEAVE
RET

Compiling and Running

To compile the Postfix code directly, pf2asm can be used:

pf2asm traverse.pf
yasm -felf traverse.asm