|
|
(3 intermediate revisions by the same user not shown) |
Line 1: |
Line 1: |
| {{TOCright}}
| | #REDIRECT [[ist:Code Generation/Exercise 10]] |
| == Problema ==
| |
| | |
| Considere o seguinte código C++ (assuma que ponteiros e '''int''' ocupam 32 bits e que '''double''' ocupa 64 bits).
| |
| | |
| <cpp>
| |
| double forall(double *v) {
| |
| const static int limit = 1024;
| |
| for (int i = 0; i < limit; i++) {
| |
| v[i] = 3 * i;
| |
| if (v[i] > 2 * i) v[i] = limit;
| |
| }
| |
| return *v;
| |
| }
| |
| </cpp>
| |
| | |
| == Código Postfix (não optimizado) ==
| |
| | |
| O código Postfix correspondente à função é o seguinte (agradece-se a comunicação de questões relativas a este código).
| |
| | |
| No código Postfix, '''BB#''' significa "[[Optimization Topics|bloco básico]] número".
| |
| | |
| <asm>
| |
| TEXT
| |
| ALIGN
| |
| GLOBAL forall, FUNC
| |
| LABEL forall
| |
| ENTER 4 ; i@-4 v@+8
| |
| | |
| ; define "limit" (this is not an assignment)
| |
| RODATA
| |
| ALIGN
| |
| LABEL limit
| |
| CONST 1024
| |
| ; done - go back to code segment
| |
| TEXT
| |
| ALIGN
| |
| | |
| ; initialize for-loop control variable (again, not an assignment)
| |
| INT 0
| |
| LOCAL -4
| |
| STORE ; i = 0
| |
| | |
| ; for-loop test
| |
| LOCAL -4
| |
| LOAD ; i
| |
| ADDR limit
| |
| LOAD ; limit
| |
| LT ; i<limit
| |
| JZ forend
| |
| | |
| ; BEGIN for-loop body
| |
| | |
| ; BEGIN assignment to v[i]
| |
| | |
| ; compute and promote 3*i
| |
| INT 3
| |
| LOCAL -4 ; &i
| |
| LOAD ; i
| |
| MUL
| |
| I2D
| |
| | |
| DDUP ; implement assignment value
| |
| | |
| ; compute &v[i] == v+i*sizeof(double)
| |
| LOCAL +8 ; &v
| |
| LOAD ; v
| |
| LOCAL -4 ; &i
| |
| LOAD ; i
| |
| INT 8 ; sizeof(double)
| |
| MUL
| |
| ADD ; &v[i]
| |
| | |
| DSTORE ; do assignment of double value
| |
| | |
| TRASH 8 ; discard value of assignment
| |
| | |
| ; END assignment to v[i]
| |
| | |
| ; if condition
| |
| ; compute &v[i] == v+i*sizeof(double)
| |
| LOCAL +8 ; &v
| |
| LOAD ; v
| |
| LOCAL -4 ; &i
| |
| LOAD ; i
| |
| INT 8 ; sizeof(double)
| |
| MUL
| |
| ADD ; &v[i]
| |
| DLOAD ; v[i]
| |
| | |
| ; compute and promote 2*i
| |
| INT 2
| |
| LOCAL -4 ; &i
| |
| LOAD ; i
| |
| MUL
| |
| I2D
| |
| | |
| ; compare
| |
| DCMP
| |
| INT 0
| |
| GT
| |
| | |
| ; BEGIN if block
| |
| ; do assignment (double)
| |
| | |
| ; load and promote "limit"
| |
| ADDR limit
| |
| LOAD
| |
| I2D
| |
| | |
| DDUP ; implement assignment value
| |
| | |
| ; compute &v[i] == v+i*sizeof(double)
| |
| LOCAL +8 ; &v
| |
| LOAD ; v
| |
| LOCAL -4 ; &i
| |
| LOAD ; i
| |
| INT 8 ; sizeof(double)
| |
| MUL
| |
| ADD ; &v[i]
| |
| | |
| DSTORE ; do assignment of double value
| |
| | |
| TRASH 8 ; discard value of assignment
| |
| | |
| ; END if block
| |
| ; END for-loop body
| |
| | |
| ; return *v
| |
| LOCAL +8 ; &v
| |
| LOAD ; v
| |
| DLOAD ; *v
| |
| DPOP
| |
| LEAVE
| |
| RET
| |
| | |
| </asm>
| |
| | |
| == Compiling and Running ==
| |
| | |
| Para compilar o código Postfix directamente, pode ser utilizada a ferramenta [[pf2asm]] (assumindo uma arquitectura de 32 bits):
| |
| | |
| pf2asm forall.pf
| |
| yasm -felf forall.asm
| |
| | |
| [[category:Compiladores]]
| |
| [[category:Ensino]]
| |