void gen_ident_elem(FILE *outfile,exprtype op,datatype_t *pdt) { fprintf(outfile,"_"); gen_op(outfile,op); fprintf(outfile,"_"); gen_sr_pdt(outfile,pdt,PDT_SRED); fprintf(outfile,"_IDENTITY"); }
void gen_op_stmt(FILE *outfile,exprtype op,datatype_t *pdt) { fprintf(outfile,"_"); gen_op(outfile,op); fprintf(outfile,"_STMT"); if (datatype_complex(pdt)) { fprintf(outfile,"_"); gen_sr_pdt(outfile,pdt,PDT_SRED); } }
void gen_list_call(cmem *b,TRASH *t,GEN_OP *o,GEN_ITEM_CALL *it,GEN_LIST_CALL *lc){ int n=rnd()%4+2; GEN_ITEM_CALL list[7]; int n_o=rnd()%(n+1); int n_i=rnd()%n; int n_c=rnd()%n; bool st=o->st; for (int i=0;i<n;i++){ if (i==n_o){ o->st=st; }else{ o->st=false; } list[i].offset=b->size; list[i].narg=rnd()%8; o->narg=list[i].narg; gen_call_op(b,t,o); } o->st=st; cmem g; init_reg_var(t); it->offset=b->size; for (int i=0;i<n;i++){ int k=rnd()%8; gen_block(&g,t,k); restore_regs(&g,t); if (n_c==i && lc){//вставляем call из аргумена for (int j=0;j<lc->count;j++){ gen_list_push(&g,t,lc->list[j].narg); _CALL_C(&g,(lc->list[j].offset)-(b->size+9+g.size+5)); int k=rnd()%8; gen_block(&g,t,k); restore_regs(&g,t); } } if ((n_i==i) && n_o==n && o->st){//между call инструкция!!! gen_op(&g,o); } gen_list_push(&g,t,list[i].narg); _CALL_C(&g,(list[i].offset)-(b->size+9+g.size+5)); } restore_regs(&g,t); GEN_CALL gc; gc.loc=t->l_size; gc.narg=it->narg; gen_call(b,&gc,&g); }
void gen_call_op(cmem *b,TRASH *t,GEN_OP *o){ cmem g; init_reg_var(t); int n1=rnd()%10+3; int n2=rnd()%10+3; gen_block(&g,t,n1); if (o->st){ restore_reg(&g,t,o->reg1); restore_reg(&g,t,o->reg2); t->lc+=gen_op(&g,o); } gen_block(&g,t,n2); restore_regs(&g,t); GEN_CALL c; c.loc=t->l_size; c.narg=o->narg; gen_call(b,&c,&g); }
/* generate a test. set 'inv' to invert test. Stack entry is popped */ int gtst(int inv, int t) { int v, *p; v = vtop->r & VT_VALMASK; if (v == VT_CMP) { /* fast case : can jump directly since flags are set */ g(0x0f); t = psym((vtop->c.i - 16) ^ inv, t); } else if (v == VT_JMP || v == VT_JMPI) { /* && or || optimization */ if ((v & 1) == inv) { /* insert vtop->c jump list in t */ p = &vtop->c.i; while (*p != 0) p = (int *)(cur_text_section->data + *p); *p = t; t = vtop->c.i; } else { t = gjmp(t); gsym(vtop->c.i); } } else { if (is_float(vtop->type.t) || (vtop->type.t & VT_BTYPE) == VT_LLONG) { vpushi(0); gen_op(TOK_NE); } if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { /* constant jmp optimization */ if ((vtop->c.i != 0) != inv) t = gjmp(t); } else { v = gv(RC_INT); o(0x85); o(0xc0 + v * 9); g(0x0f); t = psym(0x85 ^ inv, t); } } vtop--; return t; }
// Generate a test. set 'inv' to invert test. Stack entry is popped. int gtst(int inv, int t) { int v, r, *p; v = vtop->r & VT_VALMASK; if (v == VT_CMP) { // Fast case: can jump directly since flags are set t = gjmp(t, vtop->c.i ^ inv); // jcc t } else if (v == VT_JMP || v == VT_JMPI) { // && or || optimization if ((v & 1) == inv) { // Insert vtop->c jump list in t p = &vtop->c.i; while (*p != 0) { p = &branch[*p].target; } *p = t; t = vtop->c.i; } else { t = gjmp(t, 0); gsym(vtop->c.i); } } else { if (is_float(vtop->type.t) || (vtop->type.t & VT_BTYPE) == VT_LLONG) { vpushi(0); gen_op(TOK_NE); } if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { // Constant jmp optimization if ((vtop->c.i != 0) != inv) t = gjmp(t, 0); } else { r = gv(RC_INT); o(0x85); // test r,r o(0xc0 + r * 9); t = gjmp(t, TOK_NE ^ inv); // jz/jnz t } } vtop--; return t; }
void CCompiler::Compile(CParser *pParser) { struct nvfx_src tmp; struct nvfx_relocation reloc; std::vector<u32> insns_pos; std::list<struct nvfx_relocation> label_reloc; int i,nICount = pParser->GetInstructionCount(); struct nvfx_src none = nvfx_src(nvfx_reg(NVFXSR_NONE,0)); struct nvfx_insn tmp_insn,*insns = pParser->GetInstructions(); Prepare(pParser); for(i=0;i<nICount;i++) { /* u32 idx = (u32)insns_pos.size(); */ struct nvfx_insn *insn = &insns[i]; insns_pos.push_back(m_nInstructions); switch(insn->op) { case OPCODE_NOP: tmp_insn = arith(0,none.reg,0,none,none,none); emit_insn(gen_op(NOP,VEC),&tmp_insn); break; case OPCODE_ABS: tmp_insn = arith_ctor(insn,insn->dst,abs(insn->src[0]),none,none); emit_insn(gen_op(MOV,VEC),&tmp_insn); break; case OPCODE_ADD: emit_insn(gen_op(ADD,VEC),insn); break; case OPCODE_ARA: break; case OPCODE_ARL: break; case OPCODE_ARR: break; case OPCODE_BRA: reloc.location = m_nInstructions; reloc.target = insn->dst.index; label_reloc.push_back(reloc); tmp_insn = arith(0,none.reg,0,none,none,none); emit_insn(gen_op(BRA,SCA),&tmp_insn); break; case OPCODE_CAL: reloc.location = m_nInstructions; reloc.target = insn->dst.index; label_reloc.push_back(reloc); tmp_insn = arith(0,none.reg,0,none,none,none); emit_insn(gen_op(CAL,SCA),&tmp_insn); break; case OPCODE_COS: emit_insn(gen_op(COS,SCA),insn); break; case OPCODE_DP3: emit_insn(gen_op(DP3,VEC),insn); break; case OPCODE_DP4: emit_insn(gen_op(DP4,VEC),insn); break; case OPCODE_DPH: emit_insn(gen_op(DPH,VEC),insn); break; case OPCODE_DST: emit_insn(gen_op(DST,VEC),insn); break; case OPCODE_EX2: emit_insn(gen_op(EX2,SCA),insn); break; case OPCODE_EXP: emit_insn(gen_op(EXP,SCA),insn); break; case OPCODE_FLR: emit_insn(gen_op(FLR,VEC),insn); break; case OPCODE_FRC: emit_insn(gen_op(FRC,VEC),insn); break; case OPCODE_LG2: emit_insn(gen_op(LG2,SCA),insn); break; case OPCODE_LIT: emit_insn(gen_op(LIT,SCA),insn); break; case OPCODE_LOG: emit_insn(gen_op(LOG,SCA),insn); break; case OPCODE_MAD: emit_insn(gen_op(MAD,VEC),insn); break; case OPCODE_MAX: emit_insn(gen_op(MAX,VEC),insn); break; case OPCODE_MIN: emit_insn(gen_op(MIN,VEC),insn); break; case OPCODE_MOV: emit_insn(gen_op(MOV,VEC),insn); break; case OPCODE_MUL: emit_insn(gen_op(MUL,VEC),insn); break; case OPCODE_POW: tmp = nvfx_src(temp()); tmp_insn = arith(0, tmp.reg, NVFX_VP_MASK_X, none, none, insn->src[0]); emit_insn(gen_op(LG2,SCA),&tmp_insn); tmp_insn = arith(0, tmp.reg, NVFX_VP_MASK_X, swz(tmp, X, X, X, X), insn->src[1], none); emit_insn(gen_op(MUL,VEC),&tmp_insn); tmp_insn = arith_ctor(insn, insn->dst, none, none, swz(tmp, X, X, X, X)); emit_insn(gen_op(EX2,SCA),&tmp_insn); break; case OPCODE_RCC: emit_insn(gen_op(RCC,SCA),insn); break; case OPCODE_RCP: emit_insn(gen_op(RCP,SCA),insn); break; case OPCODE_RSQ: emit_insn(gen_op(RSQ,SCA),insn); break; case OPCODE_SEQ: emit_insn(gen_op(SEQ,VEC),insn); break; case OPCODE_SFL: emit_insn(gen_op(SFL,VEC),insn); break; case OPCODE_SGE: emit_insn(gen_op(SGE,VEC),insn); break; case OPCODE_SGT: emit_insn(gen_op(SGT,VEC),insn); break; case OPCODE_SIN: emit_insn(gen_op(SIN,SCA),insn); break; case OPCODE_SLE: emit_insn(gen_op(SLE,VEC),insn); break; case OPCODE_SLT: emit_insn(gen_op(SLT,VEC),insn); break; case OPCODE_SNE: emit_insn(gen_op(SNE,VEC),insn); break; case OPCODE_SSG: emit_insn(gen_op(SSG,VEC),insn); break; case OPCODE_STR: emit_insn(gen_op(STR,VEC),insn); break; case OPCODE_SUB: tmp_insn = arith_ctor(insn,insn->dst,insn->src[0],none,neg(insn->src[2])); emit_insn(gen_op(ADD,VEC),&tmp_insn); break; case OPCODE_END: if(m_nInstructions) m_pInstructions[m_nCurInstruction].data[3] |= NVFX_VP_INST_LAST; else { tmp_insn = arith(0,none.reg,0,none,none,none); emit_insn(gen_op(NOP,VEC),&tmp_insn); m_pInstructions[m_nCurInstruction].data[3] |= NVFX_VP_INST_LAST; } break; } release_temps(); } for(std::list<struct nvfx_relocation>::iterator it = label_reloc.begin();it!=label_reloc.end();it++) { struct nvfx_relocation hw_reloc; hw_reloc.location = it->location; hw_reloc.target = insns_pos[it->target]; m_lBranchRelocation.push_back(hw_reloc); } }
void gen_expression(tree_t *t) { char *reg; // If the tree is actually a function, then take care of it here. if (t->type == FUNCTION) { // Push the arguments on the stack and call the function int num_args = gen_expression_list(t->right); fprintf(yyout, "\tcall\tsubprog%s\n", t->left->attribute.variable->name); // Move the top of the stack back down below the arguments fprintf(yyout, "\taddl\t$%d, %%esp\n", 4*num_args); // Move the answer to the top of the register stack fprintf(yyout, "\tmovl\t%%eax, %s\n", stack_top(registers)); } // Case 0: else if (t->right == NULL && t->left == NULL && t->label == 1) { if (t->type == ID ) { fprintf(yyout, "\tmovl\t%s, %s\n", find_variable(t), stack_top(registers)); } else if (t->type == INUM) { fprintf(yyout, "\tmovl\t$%i, %s\n", t->attribute.ival, stack_top(registers)); } else { yywarn("Type not supported"); } } else { // Case 1: if (t->right->label == 0) { // Go to left gen_expression(t->left); if (t->right->type == ID) { gen_op(t, find_variable(t->right), stack_top(registers)); } else if (t->right->type == INUM) { sprintf(buff1, "$%i", t->right->attribute.ival); gen_op(t, buff1, stack_top(registers)); } else { yywarn("Type not supported"); } } // Case 2: else if (t->left->label >= 1 && t->right->label > t->left->label && t->left->label < NUM_REG) { stack_swap(registers); gen_expression(t->right); reg = pop(registers); gen_expression(t->left); gen_op(t, reg, stack_top(registers)); push(registers, reg); stack_swap(registers); } // Case 3: else if (t->right->label >= 1 && t->left->label >= t->right->label && t->right->label < NUM_REG) { gen_expression(t->left); reg = pop(registers); gen_expression(t->right); gen_op(t, stack_top(registers), reg); push(registers, reg); } // Case 4: else { yywarn("Temporaries not yet implemented"); } } }
/* generate a test. set 'inv' to invert test. Stack entry is popped */ int gtst(int inv, int t) { int v, *p, c; v = vtop->r & VT_VALMASK; if (v == VT_CMP) { c = vtop->c.i ^ inv; switch(c) { case TOK_EQ: c = IL_OP_BEQ; break; case TOK_NE: c = IL_OP_BNE_UN; break; case TOK_LT: c = IL_OP_BLT; break; case TOK_LE: c = IL_OP_BLE; break; case TOK_GT: c = IL_OP_BGT; break; case TOK_GE: c = IL_OP_BGE; break; case TOK_ULT: c = IL_OP_BLT_UN; break; case TOK_ULE: c = IL_OP_BLE_UN; break; case TOK_UGT: c = IL_OP_BGT_UN; break; case TOK_UGE: c = IL_OP_BGE_UN; break; } t = out_opj(c, t); } else if (v == VT_JMP || v == VT_JMPI) { /* && or || optimization */ if ((v & 1) == inv) { /* insert vtop->c jump list in t */ p = &vtop->c.i; while (*p != 0) p = (int *)*p; *p = t; t = vtop->c.i; } else { t = gjmp(t); gsym(vtop->c.i); } } else { if (is_float(vtop->t)) { vpushi(0); gen_op(TOK_NE); } if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_FORWARD)) == VT_CONST) { /* constant jmp optimization */ if ((vtop->c.i != 0) != inv) t = gjmp(t); } else { v = gv(RC_INT); t = out_opj(IL_OP_BRTRUE - inv, t); } } vtop--; return t; }
void gen_op_op(FILE *outfile,exprtype op) { fprintf(outfile,"_OP_"); gen_op(outfile,op); }