InterCodes translate_Struct(node *Exp,Operand place){ InterCodes code1 = InterCodes_init(); int size = 0; if(strcmp(Exp->child->child->name,"ID") == 0){ //ID1.ID2 node *ID2 = Exp->child->brother->brother; node *ID1 = Exp->child->child; //char typename[20]; //strcpy(typename,FindStruct(ID1->node_value,ID2->node_value)); FieldList p = Findname(ID1->node_value); p = p->brother; while(p!=NULL){ if(strcmp(p->name,Exp->child->brother->brother->node_value) == 0) break; size = size + getSize(p); p = p->brother; } Operand op1 = new_operand_name(ID1->node_value);op1->kind = ADDR_op; Operand op2 = new_operand(1,size); code1->code = new_interCode(ADDR); code1->code->binop.result = place; code1->code->binop.op1 = op1; code1->code->binop.op2 = op2; //place->kind = ADDR_op; return code1; } else if(strcpy(Exp->child->child->name,"Exp") == 0){ InterCodes code2 = InterCodes_init(); node *ID1 = Exp->child; Operand t1 = new_temp(); code1 = translate_Struct(Exp->child, t1); FieldList p = Findname(ID1->child->node_value); p = p->brother; while(p!=NULL){ if(strcmp(p->name,Exp->child->brother->brother->node_value) == 0) break; size = size + getSize(p); p = p->brother; } Operand op1 = new_operand_name(ID1->child->node_value);op1->kind = ADDR_op; Operand op2 = new_operand(1,size); code1->code = new_interCode(ADDR); code2->code->binop.result = place; code2->code->binop.op1 = op1; code2->code->binop.op2 = op2; InterCodes_link(code1,code2); //place->kind = ADDR_op; return code1; } }
static void handle_text(char *s) { char *opstart = s; operand *op; dblock *db = NULL; if (db = parse_string(&opstart,*s,8)) { add_atom(0,new_data_atom(db,1)); s = opstart; } if (!db) { op = new_operand(); s = skip_operand(s); if (parse_operand(opstart,s-opstart,op,DATA_OPERAND(8))) { atom *a; a = new_datadef_atom(8,op); a->align = 1; add_atom(0,a); } else syntax_error(8); /* invalid data operand */ } eol(s); }
static void handle_datadef(char *s,int sz) { for (;;) { char *opstart = s; operand *op; dblock *db = NULL; if (OPSZ_BITS(sz)==8 && (*s=='\"' || *s=='\'')) { if (db = parse_string(&opstart,*s,8)) { add_atom(0,new_data_atom(db,1)); s = opstart; } } if (!db) { op = new_operand(); s = skip_operand(s); if (parse_operand(opstart,s-opstart,op,DATA_OPERAND(sz))) add_atom(0,new_datadef_atom(OPSZ_BITS(sz),op)); else syntax_error(8); /* invalid data operand */ } s = skip(s); if (*s == ',') s = skip(s+1); else break; } }
static void handle_data_offset(char *s,int size,int offset) { for (;;) { char *opstart = s; operand *op; dblock *db = NULL; if (size==8 && (*s=='\"' || *s=='\'')) { if (db = parse_string(&opstart,*s,8)) { if (offset != 0) { int i; for (i=0; i<db->size; i++) db->data[i] = db->data[i] + offset; } add_atom(0,new_data_atom(db,1)); s = opstart; } } if (!db) { op = new_operand(); s = skip_operand(s); if (parse_operand(opstart,s-opstart,op,DATA_OPERAND(size))) { atom *a; if (offset != 0) op->value = make_expr(ADD,number_expr(offset),op->value); a = new_datadef_atom(abs(size),op); a->align = 1; add_atom(0,a); } else syntax_error(8); /* invalid data operand */ } s = skip(s); if (*s == ',') { s = skip(s+1); } else if (*s == commentchar) { break; } else if (*s) { syntax_error(9); /* , expected */ return; } else break; } eol(s); }
// 常量计算 Operand calc_const(IR_Type op, Operand left, Operand right) { assert(left->type == right->type && is_const(left)); assert(IR_ADD <= op && op <= IR_DIV); Operand rst = new_operand(left->type); switch (left->type) { case OPE_INTEGER: case OPE_CHAR:{ switch (op) { case IR_ADD: rst->integer = left->integer + right->integer; break; case IR_SUB: rst->integer = left->integer - right->integer; break; case IR_MUL: rst->integer = left->integer * right->integer; break; case IR_DIV: rst->integer = left->integer / right->integer; break; default: assert(0); } break; } case OPE_FLOAT: { switch (op) { case IR_ADD: rst->real = left->real + right->real; break; case IR_SUB: rst->real = left->real - right->real; break; case IR_MUL: rst->real = left->real * right->real; break; case IR_DIV: rst->real = left->real / right->real; break; default: assert(0); } break; } default: assert(0); } return rst; }
static void stab_entry(char *name,int type,int othr,int desc,char *s) { section *stabs; if (!(stabs = find_section(stabname,stabattr))) { section *str; dblock *db; stabs = new_section(stabname,stabattr,4); if (!(str = find_section(stabstrname,stabstrattr))) { str = new_section(stabstrname,stabstrattr,1); } else { if (str->pc != 0) ierror(0); } /* first byte of .stabstr is 0 */ add_atom(str,new_space_atom(number_expr(1),1,0)); /* compilation unit header has to be patched by output module */ new_stabstr(getfilename()); db = new_dblock(); db->size = 12; db->data = mymalloc(12); add_atom(stabs,new_data_atom(db,1)); } add_const_datadef(stabs,name?new_stabstr(name):0,32,1); add_const_datadef(stabs,type,8,1); add_const_datadef(stabs,othr,8,1); add_const_datadef(stabs,desc,16,1); if (s) { operand *op = new_operand(); int len = oplen(skip_operand(s),s); if (parse_operand(s,len,op,DATA_OPERAND(32))) { atom *a = new_datadef_atom(32,op); a->align = 1; add_atom(stabs,a); } else syntax_error(8); } else add_atom(stabs,new_space_atom(number_expr(4),1,0)); /* no value */ }
InterCodes translate_VarDec(node* VarDec){ InterCodes code1 = InterCodes_init(); if(strcmp(VarDec->child->name, "ID") == 0){ //ID FieldList p = Findname(VarDec->child->node_value); if(p->type->kind == Int || p->type->kind == Float){ return NULL; } else if(p->type->kind == ARRAY || p->type->kind == STRUCTVAR ){ int size = getSize(p); code1->code = new_interCode(DEC); code1->code->assign.left = new_operand_name(VarDec->child->node_value); code1->code->assign.right = new_operand(1,size); } return code1; } else //ID LB INT RB return translate_VarDec(VarDec->child); }
static void handle_data(char *s,int size,int noalign) { for (;;) { char *opstart = s; operand *op; dblock *db = NULL; if ((size==8 || size==16) && *s=='\"') { if (db = parse_string(&opstart,*s,size)) { add_atom(0,new_data_atom(db,1)); s = opstart; } } if (!db) { op = new_operand(); s = skip_operand(s); if (parse_operand(opstart,s-opstart,op,DATA_OPERAND(size))) { atom *a; a = new_datadef_atom(size,op); if (noalign) a->align=1; add_atom(0,a); } else syntax_error(8); /* invalid data operand */ } s = skip(s); if (*s == ',') { s = skip(s+1); } else if (*s==commentchar) break; else if (*s) { syntax_error(9); /* , expected */ return; } else break; } eol(s); }
static void add_const_datadef(section *s,taddr val,int size,int align) { char buf[32]; int len; operand *op; if (size <= 32) { len = sprintf(buf,"%ld",(long)val); op = new_operand(); if (parse_operand(buf,len,op,DATA_OPERAND(size))) { atom *a = new_datadef_atom(size,op); a->align = align; add_atom(s,a); } else syntax_error(8); } else ierror(0); }
Operand get_neg(Operand ope) { if (is_const(ope)) { Operand p = new_operand(ope->type); if (ope->type == OPE_INTEGER) { p->integer = -ope->integer; } else if (ope->type == OPE_FLOAT) { p->real = -ope->real; } else { LOG("Error"); assert(0); } return p; } else { LOG("Not const"); assert(0); } }
static void handle_data(char *s,int size,int noalign,int zeroterm) { expr *tree; dblock *db; do{ char *opstart=s; operand *op; if(size==8&&*s=='\"'){ s=string(s,&db); add_atom(0,new_data_atom(db,1)); }else{ op=new_operand(); s=skip_operand(s); if(!parse_operand(opstart,s-opstart,op,DATA_OPERAND(size))){ syntax_error(8); }else{ atom *a=new_datadef_atom(size,op); if(noalign) a->align=1; add_atom(0,a); } } s=skip(s); if(*s==','){ s=skip(s+1); }else if(*s) syntax_error(9); }while(*s); if(zeroterm){ if(size!=8) ierror(0); db=new_dblock(); db->size=1; db->data=mymalloc(1); *db->data=0; add_atom(0,new_data_atom(db,1)); } eol(s); }
static PyObject *get_operand(instruction_t *self, PyObject *args) { unsigned int i; xed_decoded_inst_t *decoded_inst; PyObject *r = NULL; if(PyArg_ParseTuple(args, "I", &i) == 0) goto _err; decoded_inst = self->decoded_inst; if(i >= xed_decoded_inst_noperands(decoded_inst)) { PyErr_SetString(PyExc_IndexError, "Invalid operand index"); goto _err; } r = (PyObject *)new_operand(xed_inst_operand(self->inst, i)); _err: return r; }
InterCodes translate_Cond(node* exp,Operand true_place,Operand false_place){ if(strcmp(exp->child->name,"NOT")==0){ return translate_Cond(exp->child->brother,true_place,false_place); } else if(strcmp(exp->child->brother->name,"RELOP")==0){ Operand t1 = new_temp(); Operand t2 = new_temp(); InterCodes codes1 = translate_Exp(exp->child,t1); InterCodes codes2 = translate_Exp(exp->child->brother->brother,t2); InterCodes codes3 = InterCodes_init(); codes3->code = new_interCode(COND); codes3->code->cond.op1 = t1; codes3->code->cond.op2 = t2; codes3->code->cond.op = new_operand(op,0); strcpy(codes3->code->cond.op->op,exp->child->brother->node_value); InterCodes codes4 = InterCodes_init(); codes4->code = new_interCode(GOTO); codes4->code->onlyop.op = true_place; InterCodes codes5 = InterCodes_init(); codes5->code = new_interCode(GOTO); codes5->code->onlyop.op = false_place; InterCodes_link(codes1,codes2); InterCodes_link(codes1,codes3); InterCodes_link(codes1,codes4); InterCodes_link(codes1,codes5); return codes1; } else if(strcmp(exp->child->brother->name,"AND")==0){ Operand label1 = new_label(); InterCodes codes1 = translate_Cond(exp->child, label1, false_place); InterCodes codes2 = translate_Cond(exp->child->brother->brother, true_place, false_place); InterCodes codes3 = InterCodes_init(); codes3->code = new_interCode(LAB); codes3->code->onlyop.op = label1; InterCodes_link(codes1,codes3); InterCodes_link(codes1,codes2); return codes1; } else if(strcmp(exp->child->brother->name,"OR")==0){ Operand label1 = new_label(); InterCodes codes1 = translate_Cond(exp->child, true_place, label1); InterCodes codes2 = translate_Cond(exp->child->brother->brother, true_place, false_place); InterCodes codes3 = InterCodes_init(); codes3->code = new_interCode(LAB); codes3->code->onlyop.op = label1; InterCodes_link(codes1,codes2); InterCodes_link(codes1,codes3); return codes1; } else{ /*Operand t1 = new_temp() InterCodes codes1 = translate_Exp(Exp, sym_table, t1) code2 = [IF t1 != #0 GOTO label_true] return code1 + code2 + [GOTO label_false] */ } }
InterCodes translate_Exp(node* exp,Operand place){ //-------------------------------------------------Exp ASSIGNOP Exp if(exp->exp_type == 7){ Operand t = new_temp(); InterCodes codes1 ; codes1 = translate_Exp(exp->child->brother->brother,t); if(strcmp(exp->child->child->name,"ID")==0){ InterCodes codes2 = InterCodes_init(); codes2->code = new_interCode(0); codes2->code->assign.left = new_operand_name(exp->child->child->node_value); codes2->code->assign.right = t; InterCodes_link(codes1,codes2); /*if(place != NULL){ InterCodes codes3 = InterCodes_init(); codes3->code = new_interCode(0); codes3->code->assign.left = place; codes3->code->assign.right = codes2->code->assign.left; InterCodes_link(codes1,codes3); }*/ } else{ Operand t2 =new_temp(); InterCodes codes2 = translate_Exp(exp->child,t2); if(place != NULL){ InterCodes codes3 = InterCodes_init(); codes3->code = new_interCode(0); codes3->code->assign.left = place; codes3->code->assign.right = t2; InterCodes_link(codes1,codes3); } } return codes1; } //-------------------------------------------------Exp AND Exp else if(exp->exp_type == 8){ Operand label1 = new_label(); Operand label2 = new_label(); InterCodes codes1 = InterCodes_init(); codes1->code = new_interCode(0); codes1->code->assign.left = place; codes1->code->assign.right = new_operand(1,0); InterCodes codes2 = translate_Cond(exp, label1, label2); InterCodes codes3 = InterCodes_init(); codes3->code = new_interCode(5); codes3->code->onlyop.op = label1; InterCodes codes4 = InterCodes_init(); codes4->code = new_interCode(0); codes4->code->assign.left = place; codes4->code->assign.right = new_operand(1,1); InterCodes codes5 = InterCodes_init(); codes5->code = new_interCode(LAB); codes5->code->onlyop.op = label2; InterCodes_link(codes1,codes2); InterCodes_link(codes1,codes3); InterCodes_link(codes1,codes4); InterCodes_link(codes1,codes5); return codes1; } //-------------------------------------------------Exp OR Exp else if(exp->exp_type == 9){ Operand label1 = new_label(); Operand label2 = new_label(); InterCodes codes1 = InterCodes_init(); codes1->code = new_interCode(0); codes1->code->assign.left = place; codes1->code->assign.right = new_operand(1,0); InterCodes codes2 = translate_Cond(exp, label1, label2); InterCodes codes3 = InterCodes_init(); codes3->code = new_interCode(5); codes3->code->onlyop.op = label1; InterCodes codes4 = InterCodes_init(); codes4->code = new_interCode(0); codes4->code->assign.left = place; codes4->code->assign.right = new_operand(1,1); InterCodes codes5 = InterCodes_init(); codes5->code = new_interCode(LAB); codes5->code->onlyop.op = label2; InterCodes_link(codes1,codes2); InterCodes_link(codes1,codes3); InterCodes_link(codes1,codes4); InterCodes_link(codes1,codes5); return codes1; } //-------------------------------------------------Exp RELOP Exp else if(exp->exp_type == 10){ Operand label1 = new_label(); Operand label2 = new_label(); InterCodes codes1 = InterCodes_init(); codes1->code = new_interCode(0); codes1->code->assign.left = place; codes1->code->assign.right = new_operand(1,0); InterCodes codes2 = translate_Cond(exp, label1, label2); InterCodes codes3 = InterCodes_init(); codes3->code = new_interCode(5); codes3->code->onlyop.op = label1; InterCodes codes4 = InterCodes_init(); codes4->code = new_interCode(0); codes4->code->assign.left = place; codes4->code->assign.right = new_operand(1,1); InterCodes codes5 = InterCodes_init(); codes5->code = new_interCode(LAB); codes5->code->onlyop.op = label2; InterCodes_link(codes1,codes2); InterCodes_link(codes1,codes3); InterCodes_link(codes1,codes4); InterCodes_link(codes1,codes5); return codes1; } //-------------------------------------------------Exp PLUS Exp else if(exp->exp_type == 11){ Operand t1 = new_temp(); Operand t2 = new_temp(); InterCodes codes1 = InterCodes_init(); InterCodes codes2 = InterCodes_init(); InterCodes codes3 = InterCodes_init(); codes1 = translate_Exp(exp->child->brother->brother,t1); codes2 = translate_Exp(exp->child,t2); codes3->code = new_interCode(1);//plus codes3->code->binop.result = place; codes3->code->binop.op1 = t1; codes3->code->binop.op2 = t2; InterCodes_link(codes1,codes2); InterCodes_link(codes2,codes3); return codes1; } //-------------------------------------------------Exp MINUS Exp else if(exp->exp_type == 12){ Operand t1 = new_temp(); Operand t2 = new_temp(); InterCodes codes1 = InterCodes_init(); InterCodes codes2 = InterCodes_init(); InterCodes codes3 = InterCodes_init(); codes1 = translate_Exp(exp->child->brother->brother,t1); codes2 = translate_Exp(exp->child,t2); codes3->code = new_interCode(2);//sub codes3->code->binop.result = place; codes3->code->binop.op1 = t2; codes3->code->binop.op2 = t1; InterCodes_link(codes1,codes2); InterCodes_link(codes2,codes3); return codes1; } //--------------------------------------------------Exp STAR Exp else if(exp->exp_type == 13){ Operand t1 = new_temp(); Operand t2 = new_temp(); InterCodes codes1 = InterCodes_init(); InterCodes codes2 = InterCodes_init(); InterCodes codes3 = InterCodes_init(); codes1 = translate_Exp(exp->child->brother->brother,t1); codes2 = translate_Exp(exp->child,t2); codes3->code = new_interCode(3);//star codes3->code->binop.result = place; codes3->code->binop.op1 = t1; codes3->code->binop.op2 = t2; InterCodes_link(codes1,codes2); InterCodes_link(codes2,codes3); return codes1; } //--------------------------------------------------Exp DIV Exp else if(exp->exp_type == 14){ Operand t1 = new_temp(); Operand t2 = new_temp(); InterCodes codes1 = InterCodes_init(); InterCodes codes2 = InterCodes_init(); InterCodes codes3 = InterCodes_init(); codes1 = translate_Exp(exp->child->brother->brother,t1); codes2 = translate_Exp(exp->child,t2); codes3->code = new_interCode(4);//div codes3->code->binop.result = place; codes3->code->binop.op1 = t1; codes3->code->binop.op2 = t2; InterCodes_link(codes1,codes2); InterCodes_link(codes2,codes3); return codes1; } //--------------------------------------------------LP Exp RP else if(exp->exp_type == 15){ return translate_Exp(exp->child->brother,place); } //--------------------------------------------------MINUS Exp else if(exp->exp_type == 16){ Operand t1 = new_temp(); InterCodes codes1 = InterCodes_init(); InterCodes codes2 = InterCodes_init(); codes1 = translate_Exp(exp->child->brother,t1); codes2->code = new_interCode(SUB); codes2->code->binop.result = place; t1->is_min = 1; codes2->code->binop.op1 = new_operand(1,0); codes2->code->binop.op2 = t1; InterCodes_link(codes1,codes2); return codes1; } //---------------------------------------------------NOT Exp else if(exp->exp_type == 17){ Operand label1 = new_label(); Operand label2 = new_label(); InterCodes codes1 = InterCodes_init(); codes1->code = new_interCode(0); codes1->code->assign.left = place; codes1->code->assign.right = new_operand(1,0); InterCodes codes2 = translate_Cond(exp, label1, label2); InterCodes codes3 = InterCodes_init(); codes3->code = new_interCode(5); codes3->code->onlyop.op = label1; InterCodes codes4 = InterCodes_init(); codes4->code = new_interCode(0); codes4->code->assign.left = place; codes4->code->assign.right = new_operand(1,1); InterCodes codes5 = InterCodes_init(); codes5->code = new_interCode(LAB); codes5->code->onlyop.op = label2; InterCodes_link(codes1,codes2); InterCodes_link(codes1,codes3); InterCodes_link(codes1,codes4); InterCodes_link(codes1,codes5); return codes1; } //---------------------------------------------------ID LP Args RP else if(exp->exp_type == 18){ Operand* arg_list = (Operand*)malloc(sizeof(Operand)*8); int arg_num = 0; InterCodes codes1 = translate_Args(exp->child->brother->brother,arg_list,&arg_num); if (strcmp(exp->child->node_value,"write")==0){ InterCodes codes2 = InterCodes_init(); codes2->code = new_interCode(WRITE); codes2->code->onlyop.op = arg_list[0]; InterCodes_link(codes1,codes2); return codes1; } int i = 0; for(;i < arg_num;i++){ InterCodes codes2 = InterCodes_init(); codes2->code = new_interCode(ARG);//codes2->code->kind = REFERENCE; //////////////////////////////// codes2->code->onlyop.op = arg_list[i]; InterCodes_link(codes1,codes2); } InterCodes codes3 = InterCodes_init(); codes3->code = new_interCode(CALL); codes3->code->assign.left = place; codes3->code->assign.right = new_operand_name(exp->child->node_value); InterCodes_link(codes1,codes3); return codes1; } //---------------------------------------------------ID LP RP else if(exp->exp_type == 19){ InterCodes codes = InterCodes_init(); if(strcmp(exp->child->node_value,"read")==0){ codes->code = new_interCode(READ); codes->code->onlyop.op = place; } /*else if(strcmp(exp->child->name,"write")==0){ InterCodes codes = InterCodes_init(); codes->code = new_interCode(READ); codes->code->onlyop.op = place; }*/ else{ codes->code = new_interCode(CALL); codes->code->assign.left = place; codes->code->assign.right = new_operand_name(exp->child->name); } return codes; } //--------------------------------------------------Exp LB Exp RB else if(exp->exp_type == 20){ return translate_Array(exp,place); } //--------------------------------------------------Exp DOT ID else if(exp->exp_type == 21){ return translate_Struct(exp,place); } //---------------------------------------------------ID else if(exp->exp_type == 22){ InterCodes codes = InterCodes_init(); codes->code = new_interCode(0); codes->code->assign.right = new_operand_name(exp->node_value); codes->code->assign.left = place; return codes; } //--------------------------------------------------INT else if(exp->exp_type == 23){ InterCodes codes = InterCodes_init(); codes->code = new_interCode(0); codes->code->assign.right = new_operand(1,exp->node_int); codes->code->assign.left = place; return codes; } //--------------------------------------------------FLOAT else if(exp->exp_type == 24){ } }
Operand new_label(){ Operand op = new_operand(4,label_num); label_num++; return op; }
InterCodes translate_Array(node *Exp,Operand place){ InterCodes code1 = NULL; FieldList p = Findname(Exp->child->child->node_value); int size =0; //Operand t ; if(strcpy(Exp->child->child->name,"ID") == 0){ //Exp[Exp] if(p->type->array.elem->kind == STRUCTURE) size = getSize(p); else size = 4; Operand op1 = new_operand_name(Exp->child->child->node_value); InterCodes code2,code3,code4; Operand t1 = new_temp(); code2 = translate_Exp(Exp->child->brother->brother,t1); //翻译[]中的exp Operand t2 = new_temp(); Operand c1 = new_operand(1,size); code3 = InterCodes_init(); code3->code = new_interCode(MUL); code3->code->binop.result = t2; code3->code->binop.op1 = t1; code3->code->binop.op2 = c1; code4 = InterCodes_init(); code4->code = new_interCode(ADDR); code4->code->binop.result = place; code4->code->binop.op1 = op1; code4->code->binop.op2 = t2; /*InterCodes_link(code1,code2); InterCodes_link(code1,code3); InterCodes_link(code1,code4);*/ InterCodes_link(code2,code3); InterCodes_link(code2,code4); place->kind = ADDR_op; return code2; } else if(strcpy(Exp->child->child->name,"Exp") == 0) //Exp[Exp][Exp] { if(p->type->array.elem->kind == STRUCTURE) size = getSize(p); else size = 4; InterCodes code = InterCodes_init(); Operand temp = new_temp(); code = translate_Array(Exp->child,temp); Operand op1 = new_operand_name(Exp->child->child->node_value); InterCodes code2,code3,code4; Operand t1 = new_temp(); code2 = translate_Exp(Exp->child->brother->brother,t1); //翻译[]中的exp Operand t2 = new_temp(); Operand c1 = new_operand(1,size); code3 = InterCodes_init(); code3->code = new_interCode(MUL); code3->code->binop.result = t2; code3->code->binop.op1 = t1; code3->code->binop.op2 = c1; code4 = InterCodes_init(); code4->code = new_interCode(ADDR); code4->code->binop.result = place; code4->code->binop.op1 = op1; code4->code->binop.op2 = t2; /*InterCodes_link(code1,code2); InterCodes_link(code1,code3); InterCodes_link(code1,code4); InterCodes_link(code1,code);*/ InterCodes_link(code2,code3); InterCodes_link(code2,code4); InterCodes_link(code2,code); place->kind = ADDR_op; return code2; } }