void gen_asm_read(IR *ir) { int x = allocate(ir->rd); set_dirty(x); emit_asm(jal, "read"); emit_asm(move, "%s, $v0", reg_to_s(x)); }
void gen_asm_div(IR *ir) { int y = ensure(ir->rs); int z = ensure(ir->rt); int x = allocate(ir->rd); set_dirty(x); emit_asm(div, "%s, %s", reg_to_s(y), reg_to_s(z)); emit_asm(mflo, "%s", reg_to_s(x)); }
void gen_asm_return(IR *ir) { if (curr_func->has_subroutine) { emit_asm(lw, "$ra, %d($sp) # retrieve return address", sp_offset); } int x = ensure(ir->rs); int size = curr_func->has_subroutine ? curr_func->size + 4 : curr_func->size; emit_asm(addiu, "$sp, $sp, %d # release stack space", size); emit_asm(move, "$v0, %s # prepare return value", reg_to_s(x)); emit_asm(jr, "$ra"); }
void gen_asm_func(IR *ir) { fprintf(asm_file, "%s:\n", print_operand(ir->rs)); // Spare stack space curr_func = ir->rs; sp_offset = curr_func->size; int ra = curr_func->has_subroutine ? 4 : 0; emit_asm(addi, "$sp, $sp, %d # only for variables, not records", -ir->rs->size - ra); if (curr_func->has_subroutine) { emit_asm(sw, "$ra, %d($sp) # Save return address", sp_offset); } }
// ir->rt should be OPE_INTEGER void gen_asm_addi(Operand dst, Operand src, int imm) { int first = ensure(src); int dest = allocate(dst); set_dirty(dest); emit_asm(addi, "%s, %s, %d", reg_to_s(dest), reg_to_s(first), imm); }
void gen_asm_assign(IR *ir) { int src = ensure(ir->rs); int dst = allocate(ir->rd); set_dirty(dst); emit_asm(move, "%s, %s", reg_to_s(dst), reg_to_s(src)); }
void gen_asm_load(IR *ir) { int y = ensure(ir->rs); int x = allocate(ir->rd); set_dirty(x); emit_asm(lw, "%s, 0(%s)", reg_to_s(x), reg_to_s(y)); }
void gen_asm_call(IR *ir) { // Open space for used save registers and arguments int offset = nr_arg * 4; emit_asm(addi, "$sp, $sp, -%d # Open space for save and arguments", offset); sp_offset += offset; push_all(); IR *arg = ir; // IR is stored consecutively // Push all arguments onto stack, which is more like x86 ;-) for (int i = 1; i <= nr_arg; i++) { do { arg--; } while (arg->type != IR_ARG); // ARG may not be consecutive, // so we use a iteration to find the first ARG // before the current IR. // It is expected that there always have enough // ARG IRs that match [nr_arg] int y = ensure(arg->rs); emit_asm(sw, "%s, %d($sp)", reg_to_s(y), (i - 1) * 4); } emit_asm(jal, "%s", ir->rs->name); clear_reg_state(); int x = allocate(ir->rd); set_dirty(x); if (ir->rd->next_use != MAX_LINE || ir->rd->liveness) { emit_asm(move, "%s, $v0", reg_to_s(x)); } emit_asm(addiu, "$sp, $sp, %d # Drawback save and arguments space", offset); sp_offset -= offset; nr_arg = 0; // After translating the call, clear arg state }
void gen_asm_sub(IR *ir) { // Note, sub cannot exchange! if (ir->rt->type == OPE_INTEGER) { gen_asm_addi(ir->rd, ir->rs, -ir->rt->integer); } else { int first = ensure(ir->rs); int second = ensure(ir->rt); int dst = allocate(ir->rd); set_dirty(dst); emit_asm(sub, "%s, %s, %s", reg_to_s(dst), reg_to_s(first), reg_to_s(second)); } }
void gen_asm_add(IR *ir) { if (ir->rt->type == OPE_INTEGER) { gen_asm_addi(ir->rd, ir->rs, ir->rt->integer); } else if (ir->rs->type == OPE_INTEGER) { gen_asm_addi(ir->rd, ir->rt, ir->rs->integer); } else { int first = ensure(ir->rs); int second = ensure(ir->rt); int dst = allocate(ir->rd); set_dirty(dst); emit_asm(add, "%s, %s, %s", reg_to_s(dst), reg_to_s(first), reg_to_s(second)); } }
int main(int argc, char **argv) { int dargc; char **arg, **dargv; if (argc == 1) { printf("\nUsage :%s filename[.pas]\n\n", argv[0]); return 1; } memset(arena, 0, sizeof(arena)); printf("\nCompiling...\n"); arg = argv + 1; dargc = 0; dargv = malloc(argc * sizeof(char *)); prepare_file(arg[0]); global_env.u.program.argc = dargc; global_env.u.program.argv = dargv; /*IR = &x86_dos_interface;*/ yyparse(); fclose(ifp); if (!err_occur()) { emit_asm(); print_result(pasname); return 0; } else { clear(); print_result(pasname); return 1; } finalize(); free(dargv); return 0; }
void gen_asm_br(IR *ir) { int x = ensure(ir->rs); int y = ensure(ir->rt); switch (ir->type) { case IR_BEQ: emit_asm(beq, "%s, %s, %s", reg_to_s(x), reg_to_s(y), print_operand(ir->rd)); break; case IR_BNE: emit_asm(bne, "%s, %s, %s", reg_to_s(x), reg_to_s(y), print_operand(ir->rd)); break; case IR_BGT: emit_asm(bgt, "%s, %s, %s", reg_to_s(x), reg_to_s(y), print_operand(ir->rd)); break; case IR_BLT: emit_asm(blt, "%s, %s, %s", reg_to_s(x), reg_to_s(y), print_operand(ir->rd)); break; case IR_BGE: emit_asm(bge, "%s, %s, %s", reg_to_s(x), reg_to_s(y), print_operand(ir->rd)); break; case IR_BLE: emit_asm(ble, "%s, %s, %s", reg_to_s(x), reg_to_s(y), print_operand(ir->rd)); break; default: assert(0); } }
int main(int argc, char **argv) { BuildCtx ctx_; BuildCtx *ctx = &ctx_; int status, binmode; UNUSED(argc); parseargs(ctx, argv); if ((status = build_code(ctx))) { fprintf(stderr,"Error: DASM error %08x\n", status); return 1; } switch (ctx->mode) { case BUILD_peobj: case BUILD_raw: binmode = 1; break; default: binmode = 0; break; } if (ctx->outname[0] == '-' && ctx->outname[1] == '\0') { ctx->fp = stdout; #ifdef LUA_USE_WIN if (binmode) _setmode(_fileno(stdout), _O_BINARY); /* Yuck. */ #endif } else if (!(ctx->fp = fopen(ctx->outname, binmode ? "wb" : "w"))) { fprintf(stderr, "Error: cannot open output file '%s': %s\n", ctx->outname, strerror(errno)); exit(1); } switch (ctx->mode) { case BUILD_elfasm: case BUILD_coffasm: case BUILD_machasm: emit_asm(ctx); emit_asm_debug(ctx); break; case BUILD_peobj: emit_peobj(ctx); break; case BUILD_raw: emit_raw(ctx); break; case BUILD_bcdef: emit_bcdef(ctx); emit_lib(ctx); break; case BUILD_vmdef: emit_vmdef(ctx); emit_lib(ctx); break; case BUILD_ffdef: case BUILD_libdef: case BUILD_recdef: emit_lib(ctx); break; case BUILD_folddef: emit_fold(ctx); break; default: break; } fflush(ctx->fp); if (ferror(ctx->fp)) { fprintf(stderr, "Error: cannot write to output file: %s\n", strerror(errno)); exit(1); } fclose(ctx->fp); return 0; }
void gen_asm_goto(IR *ir) { emit_asm(j, "%s", print_operand(ir->rs)); }
void gen_asm_write(IR *ir) { int x = ensure(ir->rs); emit_asm(move, "$a0, %s", reg_to_s(x)); emit_asm(jal, "write"); }
void gen_asm_addr(IR *ir) { int x = allocate(ir->rd); set_dirty(x); emit_asm(addiu, "%s, $sp, %d # get %s's address", reg_to_s(x), sp_offset - ir->rs->address, print_operand(ir->rs)); }
int main(int argc, char **argv) { int dargc; char **arg, **dargv; if (argc == 1) { printf("\nUsage :%s [-t targetmachine] [-d stad] filename[.pas]\n\n", argv[0]); return 1; } init_spl(); arg = argv + 1; dargc = 0; dargv = malloc(argc * sizeof(char *)); /* * arguments not recognized by main is pased to * target program_begin */ while(arg) { if (**(arg) == '-') { switch(arg[0][1]) { case 't': if (strlen(*arg) == 2) { arg++; IR = find_target(*arg); } else { IR = find_target(*arg + 2); } if (IR == NULL) { printf("Can't find target %s, only x86dos and x86linux is supported.\n", *arg); return 1; } arg++; break; case 'd': { char *p = arg[1]; while (*p) { switch(*p++) { case 's': dump_source = 1; break; case 'a': dump_ast = 1; break; case 't': dump_token = 1; break; case 'd': dump_dag = 1; break; default: printf("Unkown dump option %c.\n", *(p - 1)); break; } } } arg++; arg++; break; default: dargv[dargc++] = *arg++; dargv[dargc++] = *arg++; break; } } else { prepare_file(arg[0]); break; } } global_env.u.program.argc = dargc; global_env.u.program.argv = dargv; #ifndef GENERATE_AST IR = find_target("x86dos"); #endif yyparse(); fclose(ifp); if (!err_occur()) { emit_asm(); print_result(pasname); return 0; } else { clear(); print_result(pasname); return 1; } finalize(); free(dargv); return 0; }
int main(int argc, char **argv) { BuildCtx ctx_; BuildCtx *ctx = &ctx_; int status, binmode; if (sizeof(void *) != 4*LJ_32+8*LJ_64) { fprintf(stderr,"Error: pointer size mismatch in cross-build.\n"); fprintf(stderr,"Try: make HOST_CC=\"gcc -m32\" CROSS=...\n\n"); return 1; } UNUSED(argc); parseargs(ctx, argv); if ((status = build_code(ctx))) { fprintf(stderr,"Error: DASM error %08x\n", status); return 1; } switch (ctx->mode) { case BUILD_peobj: case BUILD_raw: binmode = 1; break; default: binmode = 0; break; } if (ctx->outname[0] == '-' && ctx->outname[1] == '\0') { ctx->fp = stdout; #if defined(_WIN32) if (binmode) _setmode(_fileno(stdout), _O_BINARY); /* Yuck. */ #endif } else if (!(ctx->fp = fopen(ctx->outname, binmode ? "wb" : "w"))) { fprintf(stderr, "Error: cannot open output file '%s': %s\n", ctx->outname, strerror(errno)); exit(1); } switch (ctx->mode) { case BUILD_elfasm: case BUILD_coffasm: case BUILD_machasm: emit_asm(ctx); emit_asm_debug(ctx); break; case BUILD_peobj: emit_peobj(ctx); break; case BUILD_raw: emit_raw(ctx); break; case BUILD_bcdef: emit_bcdef(ctx); emit_lib(ctx); break; case BUILD_vmdef: emit_vmdef(ctx); emit_lib(ctx); break; case BUILD_ffdef: case BUILD_libdef: case BUILD_recdef: emit_lib(ctx); break; case BUILD_folddef: emit_fold(ctx); break; default: break; } fflush(ctx->fp); if (ferror(ctx->fp)) { fprintf(stderr, "Error: cannot write to output file: %s\n", strerror(errno)); exit(1); } fclose(ctx->fp); return 0; }
void gen_asm_store(IR *ir) { int y = ensure(ir->rt); int x = ensure(ir->rs); emit_asm(sw, "%s, 0(%s)", reg_to_s(y), reg_to_s(x)); }