void Add() { Match('+'); Term(); EmitLn("addl (%esp), %eax"); EmitLn("addl $4, %esp"); }
void DoFor() { char L1[100]; char L2[100]; Match('f'); strcpy(L1, NewLabel()); strcpy(L2, NewLabel()); char Name = GetName(); Match('='); Expression(); EmitLn("dec rax"); sprintf(tmp, "mov qword [%c], rax", Name); EmitLn(tmp); Expression(); EmitLn("push rax"); PostLabel(L1); sprintf(tmp, "mov rax, qword [%c]", Name); EmitLn(tmp); EmitLn("inc rax"); sprintf(tmp, "mov qword [%c], rax", Name); EmitLn(tmp); EmitLn("cmp rax, qword [rsp]"); sprintf(tmp, "jg %s", L2); EmitLn(tmp); Block(); Match('e'); sprintf(tmp, "jmp %s", L1); EmitLn(tmp); PostLabel(L2); EmitLn("add rsp, 8"); }
void DoWhile(void) { char code[MAXMSG]; char l1[MAXLBL]; char l2[MAXLBL]; Match('w'); NewLabel(); strncpy(l1, label, MAXLBL); NewLabel(); strncpy(l2, label, MAXLBL); PostLabel(l1); BoolExpression(); snprintf(code, MAXMSG, "je .%s", l2); EmitLn(code); Block(l2); Match('e'); // ENDWHILE printf("#ENDWHILE\n"); snprintf(code, MAXMSG, "jmp .%s", l1); EmitLn(code); PostLabel(l2); }
void DoIf() { Condition(); char L1[MAX_BUF]; char L2[MAX_BUF]; strcpy(L1, NewLabel()); strcpy(L2, L1); sprintf(tmp, "jz %s", L1); EmitLn(tmp); Block(); if (Token == 'l') { /* match *else* statement */ strcpy(L2, NewLabel()); sprintf(tmp, "jmp %s", L2); EmitLn(tmp); PostLabel(L1); Block(); } PostLabel(L2); MatchString("ENDIF"); }
void Subtract() { Match('-'); Term(); EmitLn("pop rbx"); EmitLn("sub rax, rbx"); EmitLn("neg rax"); }
void BoolXor() { Match('~'); BoolTerm(); EmitLn("xor (%esp), %eax"); EmitLn("addl $4, %esp"); /* recover the stack */ }
void DoIf(char *L) { char L1[MAX_BUF]; char L2[MAX_BUF]; strcpy(L1, NewLabel()); strcpy(L2, L1); Match('i'); BoolExpression(); sprintf(tmp, "jz %s", L1); EmitLn(tmp); Block(L); dprint("DoIf: Got Look = %c\n", Look); if (Look == 'l') { /* match *else* statement */ Match('l'); strcpy(L2, NewLabel()); sprintf(tmp, "jmp %s", L2); EmitLn(tmp); PostLabel(L1); Block(L); } Match('e'); PostLabel(L2); }
void DoDo(void) { char code[MAXMSG]; char l1[MAXLBL]; char l2[MAXLBL]; Match('d'); NewLabel(); strncpy(l1, label, MAXLBL); NewLabel(); strncpy(l2, label, MAXLBL); // exit point printf("# DO\n"); Expression(); // expr1 = repeat count EmitLn("pushl %eax\t\t# repeat count"); PostLabel(l1); Block(l2); EmitLn("popl %ecx"); EmitLn("dec %ecx"); EmitLn("pushl %ecx"); // test snprintf(code, MAXMSG, "jnz .%s", l1); EmitLn(code); Match('e'); // ENDWHILE printf("#ENDDO\n"); PostLabel(l2); }
void Greater() { Match('>'); Expression(); EmitLn("cmp rax, [rsp]"); EmitLn("setle al"); }
void DoIf(char *exit_label) { char code[MAXMSG]; char l1[MAXLBL]; char l2[MAXLBL]; Match('i'); printf("# IF\n"); NewLabel(); strncpy(l1, label, MAXLBL); strncpy(l2, label, MAXLBL); BoolExpression(); snprintf(code, MAXMSG, "je .%s", l1); EmitLn(code); printf("# TRUE\n"); // here, tutorial 05 only matches 'e' once, after the if statement // this doesn't seem to work unless i add Look=='l' to the test in // Blocks(). Block(exit_label); if (Look=='l') { Match('l'); printf("#ELSE\n"); NewLabel(); strncpy(l2, label, MAXLBL); snprintf(code, MAXMSG, "jmp .%s", l2); EmitLn(code); PostLabel(l1); Block(exit_label); } Match('e'); // ENDIF printf("#ENDIF\n"); PostLabel(l2); }
void Subtract() { Match('-'); Term(); EmitLn("subl (%esp), %eax"); EmitLn("negl %eax"); EmitLn("addl $4, %esp"); }
void Multiply() { Match('*'); Factor(); EmitLn("imull (%esp), %eax"); /* push of the stack */ EmitLn("addl $4, %esp"); }
void Greater() { Match('>'); Expression(); EmitLn("cmp %eax, (%esp)"); EmitLn("setg %al"); EmitLn("addl $4, %esp"); /* recover the stack */ }
void NotEquals() { Match('#'); Expression(); EmitLn("cmp (%esp), %eax"); EmitLn("setne %al"); EmitLn("addl $4, %esp"); /* recover the stack */ }
void Divide() { Match('/'); Factor(); EmitLn("mov rbx, rax"); EmitLn("pop rax"); EmitLn("cqo"); EmitLn("idiv rbx"); }
void Less() { Match('<'); Expression(); EmitLn("cmp %eax, (%esp)"); EmitLn("setl %al"); EmitLn("addl $4, %esp"); /* recover the stack */ }
void Header() { EmitLn("extern printf"); EmitLn("extern scanf"); EmitLn("section .data"); printf("fmt: db \"%%d\", 10, 0\n"); printf("fmtin: db \"%%d\", 0\n"); }
void Assignment() { char c = GetName(); Match('='); BoolExpression(); sprintf(tmp, "lea %c, %%ebx", c); EmitLn(tmp); EmitLn("movl %eax, (%ebx)"); }
void Equals() { Match('='); Expression(); EmitLn("cmp (%esp), %eax"); /* Note that 80386 has setcc corresponds to 86000's SETCC * However, it only takes 8-bit registers */ EmitLn("sete %al"); EmitLn("addl $4, %esp"); /* recover the stack */ }
void Assignment() { char name[MAX_BUF]; strcpy(name, Value); Match('='); Expression(); sprintf(tmp, "lea %s, %%ebx", name); EmitLn(tmp); EmitLn("movl %eax, (%ebx)"); }
void BoolTerm() { NotFactor(); while (Look == '&') { EmitLn("push rax"); Match('&'); NotFactor(); EmitLn("and rax, [rsp]"); EmitLn("add rsp, 8"); } }
void BoolTerm() { NotFactor(); while(Look == '&') { EmitLn("pushl %eax"); Match('&'); NotFactor(); EmitLn("and (%esp), %eax"); EmitLn("addl $4, %esp"); } }
void BoolFactor() { if (IsBoolean(Look)) { if (GetBoolean()) { EmitLn("movl $-1, %eax"); } else { EmitLn("xor %eax, %eax"); } } else { Relation(); } }
void Ident() { char Name = GetName(); if(Look == ('(')) { Match('('); Match(')'); sprintf(tmp, "call %c", Name); EmitLn(tmp); } else { sprintf(tmp, "mov rax, [%c]", Name); EmitLn(tmp); } }
void Ident() { GetName(); if (Look == '(') { Match('('); Match(')'); sprintf(tmp, "call %s", Value); EmitLn(tmp); } else { sprintf(tmp, "movl %s, %%eax", Value); EmitLn(tmp); } }
void Ident() { char c = GetName(); if (Look == '(') { Match('('); Match(')'); sprintf(tmp, "call %c", c); EmitLn(tmp); } else { sprintf(tmp, "movl %c, %%eax", c); EmitLn(tmp); } }
void BoolFactor() { if(IsBoolean(Look)) { if(GetBoolean()) { EmitLn("mov rax, -1"); } else { EmitLn("xor rax, rax"); } } else { Relation(); } }
void Relation() { Expression(); if (IsRelop(Look)) { EmitLn("push rax"); switch(Look) { case '=': Equals(); break; case '#': NotEquals(); break; case '<': Less(); break; case '>': Greater(); break; } EmitLn("add rsp, 8"); EmitLn("cmp rax, 0"); } }
/* Adjust the stack pointer upwards by n bytes */ void CleanStack(int bytes) { if (bytes > 0) { sprintf(tmp, "addl $%d, %%esp", bytes); EmitLn(tmp); } }
void Assignment() { char Name = GetName(); Match('='); BoolExpression(); sprintf(tmp, "mov [%c], rax", Name); EmitLn(tmp); }