AMODE *GenerateShift(ENODE *node,int flags, int size, int op) { AMODE *ap1, *ap2, *ap3; ap3 = GetTempRegister(); ap1 = GenerateExpression(node->p[0],F_REG,size); ap2 = GenerateExpression(node->p[1],F_REG | F_IMMED,8); MaskShift(op, ap1, GetNaturalSize(node->p[0])); if (ap2->mode==am_immed) { switch(op) { case op_asl: op = op_asli; break; case op_sll: op = op_slli; break; case op_shl: op = op_shli; break; case op_shlu: op = op_shlui; break; case op_asr: op = isThor?op_shri:op_asri; break; case op_sra: op = op_srai; break; case op_shr: op = op_shri; break; case op_shru: op = op_shrui; break; case op_srl: op = op_srli; break; case op_lsr: op = op_lsri; break; } GenerateTriadic(op,0,ap3,ap1,make_immed(ap2->offset->i)); } else GenerateTriadic(op,0,ap3,ap1,ap2); ReleaseTempRegister(ap2); ReleaseTempRegister(ap1); MakeLegalAmode(ap3,flags,size); return ap3; }
void GenerateFirstcall(Statement *stmt) { int lab1, lab2; char buf[20]; AMODE *ap1,*ap2; lab1 = contlab; /* save old continue label */ lab2 = breaklab; /* save old break label */ contlab = nextlabel++; /* new continue label */ if( stmt->s1 != NULL ) /* has block */ { breaklab = nextlabel++; ap1 = GetTempRegister(); GenerateDiadic(op_lb,0,ap1,make_string(stmt->fcname)); if (isThor) { GenerateDiadic(op_tst,0,make_string("p0"), ap1); GeneratePredicatedMonadic(0,PredOp(op_eq),op_br,0,make_clabel(breaklab)); } else GenerateDiadic(op_beq,0,ap1,make_clabel(breaklab)); ReleaseTempRegister(ap1); GenerateDiadic(op_sb,0,makereg(0),make_string(stmt->fcname)); GenerateStatement(stmt->s1); GenerateLabel(breaklab); breaklab = lab2; /* restore old break label */ } contlab = lab1; /* restore old continue label */ }
/* * generate shift equals operators. */ AMODE *GenerateAssignShift(ENODE *node,int flags,int size,int op) { struct amode *ap1, *ap2, *ap3; ap1 = GetTempRegister(); //size = GetNaturalSize(node->p[0]); ap3 = GenerateExpression(node->p[0],F_ALL,size); ap2 = GenerateExpression(node->p[1],F_REG | F_IMMED,size); if (ap3->mode==am_reg) GenerateDiadic(op_mov,0,ap1,ap3); else if (ap3->mode == am_immed) { error(ERR_LVALUE); if (isFISA64) FISA64_GenLdi(ap1,ap2); else GenerateDiadic(op_ldi,0,ap1,ap3); } else GenLoad(ap1,ap3,size); MaskShift(op, ap1, size); if (ap2->mode==am_immed) GenerateTriadic(op,0,ap1,ap1,make_immed(ap2->offset->i)); else GenerateTriadic(op,0,ap1,ap1,ap2); if (ap3->mode != am_reg) GenStore(ap1,ap3,size); ReleaseTempRegister(ap2); ReleaseTempRegister(ap3); MakeLegalAmode(ap1,flags,size); return ap1; }
AMODE *GenerateFunctionCall(ENODE *node, int flags) { AMODE *ap, *result; SYM *sym; int i; int msk; msk = SaveTempRegs(); sym = NULL; i = GeneratePushParameterList(node->p[1]); // Call the function if( node->p[0]->nodetype == en_nacon ) { GenerateDiadic(op_call,0,make_offset(node->p[0]),NULL); sym = gsearch(node->p[0]->sp); } else { ap = GenerateExpression(node->p[0],F_REG,8); ap->mode = am_ind; GenerateDiadic(op_jal,0,makereg(31),ap); ReleaseTempRegister(ap); } // Pop parameters off the stack if (i!=0) { if (sym) { if (!sym->IsPascal) GenerateTriadic(op_addui,0,makereg(30),makereg(30),make_immed(i * 8)); } else GenerateTriadic(op_addui,0,makereg(30),makereg(30),make_immed(i * 8)); } RestoreTempRegs(msk); result = GetTempRegister(); if( result->preg != 1 || (flags & F_REG) == 0 ) if (sym) { if (sym->tp->btp->type==bt_void) ; else GenerateDiadic(op_mov,0,result,makereg(1)); } else GenerateDiadic(op_mov,0,result,makereg(1)); return result; }
AMODE *GenerateFunctionCall(ENODE *node, int flags) { AMODE *ap, *result; SYM *sym; int i; int msk; int sp; //msk = SaveTempRegs(); sp = TempInvalidate(); sym = (SYM*)NULL; i = GeneratePushParameterList(node->p[1]); // Call the function if( node->p[0]->nodetype == en_cnacon ) { GenerateMonadic(op_jsr,0,make_offset(node->p[0])); sym = gsearch(node->p[0]->sp); } else { ap = GenerateExpression(node->p[0],F_BREG,8); ap->mode = am_brind; GenerateDiadic(op_jsr,0,makebreg(LR),ap); ReleaseTempRegister(ap); } // Pop parameters off the stack if (i!=0) { if (sym) { if (!sym->IsPascal) GenerateTriadic(op_addui,0,makereg(regSP),makereg(regSP),make_immed(i * 8)); } else GenerateTriadic(op_addui,0,makereg(regSP),makereg(regSP),make_immed(i * 8)); } //RestoreTempRegs(msk); TempRevalidate(sp); ap = GetTempRegister(); GenerateDiadic(op_mov,0,ap,makereg(1)); return ap; }
// Generate a function body. // void GenerateFunction(SYM *sym, Statement *stmt) { char buf[20]; char *bl; int cnt, nn; AMODE *ap; ENODE *ep; SYM *sp; throwlab = retlab = contlab = breaklab = -1; lastsph = 0; memset(semaphores,0,sizeof(semaphores)); throwlab = nextlabel++; while( lc_auto & 7 ) /* round frame size to word */ ++lc_auto; if (sym->IsInterrupt) { //GenerateTriadic(op_subui,0,makereg(30),makereg(30),make_immed(30*8)); //GenerateDiadic(op_sm,0,make_indirect(30), make_mask(0x9FFFFFFE)); } if (!sym->IsNocall) { GenerateTriadic(op_subui,0,makereg(SP),makereg(SP),make_immed(32)); if (lc_auto || sym->NumParms > 0) { GenerateDiadic(op_ss|op_sw,0,makereg(regBP),make_indirect(SP)); } // if (sym->UsesPredicate) GenerateDiadic(op_ss|op_sws, 0, make_string("pregs"), make_indexed(24,SP)); // For a leaf routine don't bother to store the link register or exception link register. if (!sym->IsLeaf) { if (exceptions) { GenerateDiadic(op_ss|op_sws, 0, makebreg(CLR), make_indexed(8,SP)); } GenerateDiadic(op_ss|op_sws, 0, makebreg(LR), make_indexed(16,SP)); if (exceptions) { ep = allocEnode(); ep->nodetype = en_clabcon; ep->i = throwlab; ap = allocAmode(); ap->mode = am_immed; ap->offset = ep; GenerateDiadic(op_ldis,0, makebreg(CLR), ap); } } if (lc_auto || sym->NumParms > 0) { GenerateDiadic(op_mov,0,makereg(regBP),makereg(regSP)); if (lc_auto) GenerateTriadic(op_subui,0,makereg(regSP),makereg(regSP),make_immed(lc_auto)); } // Save registers used as register variables. // **** Done in Analyze.c **** //if( save_mask != 0 ) { // GenerateTriadic(op_subui,0,makereg(SP),makereg(SP),make_immed(popcnt(save_mask)*8)); // cnt = (bitsset(save_mask)-1)*8; // for (nn = 31; nn >=1 ; nn--) { // if (save_mask & (1 << nn)) { // GenerateTriadic(op_sw,0,makereg(nn),make_indexed(cnt,SP),NULL); // cnt -= 8; // } // } //} } if (optimize) sym->NumRegisterVars = opt1(stmt); GenerateStatement(stmt); GenerateReturn(sym,0); // Generate code for the hidden default catch if (exceptions) { if (sym->IsLeaf){ if (sym->DoesThrow) { GenerateLabel(throwlab); ap = GetTempRegister(); GenerateDiadic(op_mfspr,0,ap,makebreg(CLR)); GenerateDiadic(op_mtspr,0,makebreg(LR),ap); ReleaseTempRegister(ap); GenerateMonadic(op_bra,0,make_clabel(retlab)); // goto regular return cleanup code } } else { GenerateLabel(throwlab); GenerateDiadic(op_lws,0,makebreg(regLR),make_indexed(8,regBP)); // load throw return address from stack into LR GenerateDiadic(op_sws,0,makebreg(regLR),make_indexed(16,regBP)); // and store it back (so it can be loaded with the lm) GenerateMonadic(op_bra,0,make_clabel(retlab)); // goto regular return cleanup code } } }
// Generate a function body. // void GenerateFunction(SYM *sym, Statement *stmt) { char buf[20]; char *bl; int cnt, nn; AMODE *ap; ENODE *ep; SYM *sp; std::string vep; throwlab = retlab = contlab = breaklab = -1; lastsph = 0; memset(semaphores,0,sizeof(semaphores)); throwlab = nextlabel++; retlab = nextlabel++; while( lc_auto & 7 ) /* round frame size to word */ ++lc_auto; if (sym->IsInterrupt) { //GenerateTriadic(op_subui,0,makereg(30),makereg(30),make_immed(30*8)); //GenerateDiadic(op_sm,0,make_indirect(30), make_mask(0x9FFFFFFE)); } if (sym->prolog) { if (optimize) opt1(sym->prolog); GenerateStatement(sym->prolog); } if (!sym->IsNocall) { GenerateTriadic(op_addui,0,makereg(regSP),makereg(regSP),make_immed(-GetReturnBlockSize())); if (lc_auto || sym->NumParms > 0) { GenerateDiadic(op_sw,0,makereg(regBP),make_indirect(regSP)); } // if (sym->UsesPredicate) GenerateDiadic(op_sws, 0, make_string("pregs"), make_indexed(24,regSP)); GenerateDiadic(op_sw, 0, makereg(regCLP),make_indexed(32,regSP)); // For a leaf routine don't bother to store the link register or exception link register. // Since virtual functions call other functions, they can't be leaf // routines. if (!sym->IsLeaf || sym->IsVirtual) { if (exceptions) { GenerateDiadic(op_sws, 0, makebreg(regXLR), make_indexed(8,regSP)); } GenerateDiadic(op_sws, 0, makebreg(regLR), make_indexed(16,regSP)); if (exceptions) { ep = allocEnode(); ep->nodetype = en_clabcon; ep->i = throwlab; ap = allocAmode(); ap->mode = am_immed; ap->offset = ep; GenerateDiadic(op_ldis,0, makebreg(regXLR), ap); } } GenerateDiadic(op_lw,0,makereg(regCLP),make_indexed(GetReturnBlockSize(),regSP)); vep = *sym->mangledName; vep += "_VEP"; GenerateMonadic(op_fnname,0,make_string((char *)vep.c_str())); // Generate switch to call derived methods if (sym->IsVirtual || sym->derivitives) { char buf[20]; char *buf2; DerivedMethod *mthd; dfs.printf("VirtualFunction Switch"); GenerateDiadic(op_lcu,0,makereg(24),make_indirect(regCLP)); mthd = sym->derivitives; while (mthd) { sprintf(buf, "p%d", 7); buf2 = my_strdup(buf); GenerateTriadic(op_cmpi,0,make_string(buf2),makereg(24),make_immed(mthd->typeno)); vep = *(mthd->name); vep += "_VEP"; // Virtual Entry Point GeneratePredicatedMonadic(7,PredOp(op_eq),op_jmp,0, make_string((char *)vep.c_str())); // jump to the method mthd = mthd->next; } } if (lc_auto || sym->NumParms > 0) { GenerateDiadic(op_mov,0,makereg(regBP),makereg(regSP)); if (lc_auto) GenerateTriadic(op_addui,0,makereg(regSP),makereg(regSP),make_immed(-lc_auto)); } // Save registers used as register variables. // **** Done in Analyze.c **** //if( save_mask != 0 ) { // GenerateTriadic(op_subui,0,makereg(SP),makereg(SP),make_immed(popcnt(save_mask)*8)); // cnt = (bitsset(save_mask)-1)*8; // for (nn = 31; nn >=1 ; nn--) { // if (save_mask & (1 << nn)) { // GenerateTriadic(op_sw,0,makereg(nn),make_indexed(cnt,SP),NULL); // cnt -= 8; // } // } //} } if (optimize) sym->NumRegisterVars = opt1(stmt); GenerateStatement(stmt); GenerateEpilog(sym); // Generate code for the hidden default catch if (exceptions) { if (sym->IsLeaf){ if (sym->DoesThrow) { GenerateLabel(throwlab); ap = GetTempRegister(); GenerateDiadic(op_mfspr,0,ap,makebreg(regXLR)); GenerateDiadic(op_mtspr,0,makebreg(regLR),ap); ReleaseTempRegister(ap); GenerateMonadic(op_br,0,make_clabel(retlab)); // goto regular return cleanup code } } else { GenerateLabel(throwlab); GenerateDiadic(op_lws,0,makebreg(regLR),make_indexed(8,regBP)); // load throw return address from stack into LR GenerateDiadic(op_sws,0,makebreg(regLR),make_indexed(16,regBP)); // and store it back (so it can be loaded with the lm) GenerateMonadic(op_br,0,make_clabel(retlab)); // goto regular return cleanup code } } }
AMODE *GenerateFunctionCall(ENODE *node, int flags) { AMODE *ap, *result; SYM *sym; int i; int msk; int sp; int isPascal = FALSE; dfs.puts("<GenerateFunctionCall>"); //msk = SaveTempRegs(); if (node->p[0] < (ENODE *)0x0FLL) { error(ERR_NULLPOINTER); goto xit1; } sp = TempInvalidate(); sym = (SYM*)NULL; i = GeneratePushParameterList(node->p[1]); // Call the function if( node->p[0]->nodetype == en_cnacon ) { dfs.printf("cnacon node:%s|\n",(char *)node->p[0]->sp->c_str()); // if (node->p[0]->i==25) // GenerateDiadic(op_sw,0,makereg(regCLP),make_indexed(0,regSP)); if (node->p[0]->sp < (std::string *)0x0FLL) node->p[0]->sp = new std::string("<null>"); GenerateMonadic(op_jsr,0,make_offset(node->p[0])); sym = gsearch(*node->p[0]->sp); dfs.puts((char*)(node->p[0]->sp->c_str())); if (sym) { dfs.puts("<found></found>"); } else { dfs.printf("<notfound>%s</notfound>",(char*)(node->p[0]->sp->c_str())); } } else { ap = GenerateExpression(node->p[0],F_BREG,8); ap->mode = am_brind; isPascal = node->p[0]->isPascal; GenerateDiadic(op_jsr,0,makebreg(1),ap); ReleaseTempRegister(ap); } // Pop parameters off the stack if (i!=0) { if (sym) { if (!sym->IsPascal) GenerateTriadic(op_addui,0,makereg(regSP),makereg(regSP),make_immed(i * 8)); } else if (!isPascal) GenerateTriadic(op_addui,0,makereg(regSP),makereg(regSP),make_immed(i * 8)); } //RestoreTempRegs(msk); TempRevalidate(sp); xit1: ap = GetTempRegister(); if (flags & F_NOVALUE) ; else GenerateDiadic(op_mov,0,ap,makereg(1)); dfs.puts("</GenerateFunctionCall>"); return ap; }
int FindAndTrackAllPointsOnRegistersOpenCV(unsigned int reg_new , unsigned int reg_old , unsigned int timeout) { if ( ( video_register[reg_new].pixels == 0 ) || ( video_register[reg_old].pixels == 0 ) ) { return 0; } // Load two images and allocate other structures struct VideoRegister * MONOCHROME_TMP_REGISTER_OLD = GetTempRegister(); if (MONOCHROME_TMP_REGISTER_OLD == 0 ) { fprintf(stderr," Error Getting the first temporary Video Register ( TrackAllPointsOnRegistersOpenCV ) \n"); return 0; } struct VideoRegister * MONOCHROME_TMP_REGISTER_NEW = GetTempRegister(); if (MONOCHROME_TMP_REGISTER_NEW == 0 ) { fprintf(stderr," Error Getting the second temporary Video Register ( TrackAllPointsOnRegistersOpenCV ) \n"); return 0; } CopyRegister(&video_register[reg_new],MONOCHROME_TMP_REGISTER_NEW,0,0); ConvertRegisterFrom3ByteTo1Byte(MONOCHROME_TMP_REGISTER_NEW); CopyRegister(&video_register[reg_old],MONOCHROME_TMP_REGISTER_OLD,0,0); ConvertRegisterFrom3ByteTo1Byte(MONOCHROME_TMP_REGISTER_OLD); image_1->imageData=(char*) MONOCHROME_TMP_REGISTER_OLD->pixels; // UGLY HACK image_2->imageData=(char*) MONOCHROME_TMP_REGISTER_NEW->pixels; // UGLY HACK int win_size = 15; // Get the features for tracking StartTimer(FIND_CORNERS_DELAY); // STATISTICS KEEPER FOR HYPERVISOR | START int corner_count = MAX_CORNERS; cvGoodFeaturesToTrack( image_1, eig_image, tmp_image, cornersA, &corner_count, 0.05, 5.0, 0, 3, 0, 0.04 ); cvFindCornerSubPix( image_1, cornersA, corner_count, cvSize( win_size, win_size ), cvSize( -1, -1 ), cvTermCriteria( CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 20, 0.03 ) ); EndTimer(FIND_CORNERS_DELAY); // STATISTICS KEEPER FOR HYPERVISOR | END // Call Lucas Kanade algorithm StartTimer(TRACK_CORNERS_DELAY); // STATISTICS KEEPER FOR HYPERVISOR | START char features_found[ MAX_CORNERS ]; float feature_errors[ MAX_CORNERS ]; CvSize pyr_sz = cvSize( image_1->width+8, image_2->height/3 ); IplImage* pyrA = cvCreateImage( pyr_sz, IPL_DEPTH_32F, 1 ); IplImage* pyrB = cvCreateImage( pyr_sz, IPL_DEPTH_32F, 1 ); cvCalcOpticalFlowPyrLK( image_1, image_2, pyrA, pyrB, cornersA, cornersB, corner_count, cvSize( win_size, win_size ), 5, features_found, feature_errors, cvTermCriteria( CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 20, 0.3 ), 0 ); EndTimer(TRACK_CORNERS_DELAY); // STATISTICS KEEPER FOR HYPERVISOR | END ClearFeatureList(video_register[reg_new].features); video_register[reg_new].features->last_track_time = video_register[reg_new].time; // AFTER the procedure , the feature list is up to date int i=0 ; for ( i=0; i <corner_count; i++ ) { AddToFeatureList( video_register[reg_new].features , cornersB[i].x , cornersB[i].y , 1 ,0,0,0); video_register[reg_new].features->list[i].last_x = cornersA[i].x; video_register[reg_new].features->list[i].last_y = cornersA[i].y; } unsigned int filtered_out = RemoveTrackPointsIfMovementMoreThan(video_register[reg_new].features,settings[FEATURE_TRACKING_MAX_MOVEMENT_THRESHOLD]); if ( filtered_out > 0 ) { // fprintf(stderr,"Filtered %u points due to movement\n", filtered_out ); } unsigned int outside_zone = 8; filtered_out = Remove2DTrackPointsIfOutOfBounds(video_register[reg_new].features,outside_zone,outside_zone,metrics[RESOLUTION_X]-outside_zone,metrics[RESOLUTION_Y]-outside_zone); if ( filtered_out > 0 ) { // fprintf(stderr,"Filtered %u points due as out of bounds \n", filtered_out ); } cvReleaseImage(&pyrA); cvReleaseImage(&pyrB); StopUsingVideoRegister(MONOCHROME_TMP_REGISTER_NEW); StopUsingVideoRegister(MONOCHROME_TMP_REGISTER_OLD); return corner_count; }
void GenerateSpinlock(Statement *stmt) { int lab1, lab2, lab3, lab4; AMODE *ap1, *ap2; AMODE *ap; int sp = 0; lab1 = nextlabel++; lab2 = nextlabel++; lab3 = nextlabel++; if( stmt != (Statement *)NULL && stmt->exp != (ENODE *)NULL ) { initstack(); ap1 = GetTempRegister(); ap2 = GetTempRegister(); ap = GenerateExpression(stmt->exp,F_REG,8); GenerateDiadic(op_mov,0,makereg(1),ap); if (stmt->initExpr) { if (isFISA64) FISA64_GenLdi(makereg(2),make_immed((int64_t)stmt->initExpr)); else GenerateTriadic(op_ori, 0, makereg(2),makereg(0),make_immed((int64_t)stmt->initExpr)); } else { GenerateDiadic(op_ldi,0,makereg(2),make_immed(-1)); } GenerateMonadic(op_bsr,0,make_string("_LockSema")); if (stmt->initExpr) GenerateDiadic(op_beq,0,makereg(1),make_clabel(lab2)); ReleaseTempRegister(ap); ReleaseTempRegister(ap2); ReleaseTempRegister(ap1); // We treat this statement generation like a function call and save // the used temporary beforehand. The statement might reinitialize // the expression vars. There aren't any other cases where temporaries // are needed after statements are generated. GenerateMonadic(op_push,0,ap); GenerateStatement(stmt->s1); GenerateMonadic(op_pop,0,ap); // unlock if (isRaptor64) GenerateDiadic(op_outb, 0, makereg(0), make_indexed((int64_t)stmt->incrExpr,ap->preg)); else if (isFISA64) { GenerateDiadic(op_mov, 0, makereg(1), makereg(ap->preg)); GenerateMonadic(op_bsr, 0, make_string("_UnlockSema")); } else GenerateDiadic(op_sw, 0, makereg(0), make_indexed((int64_t)stmt->incrExpr,ap->preg)); if (stmt->initExpr) { GenerateMonadic(isThor?op_br:op_bra,0,make_clabel(lab3)); GenerateLabel(lab2); GenerateStatement(stmt->s2); GenerateLabel(lab3); } else { printf("Warning: The lockfail code is unreachable because spinlock tries are infinite.\r\n"); } } //ap1 = GetTempRegister(); //ap2 = GetTempRegister(); //if (stmt->exp) { // lab2 = nextlabel++; // GenerateTriadic(op_ori,0,ap2,makereg(0),make_immed(stmt->exp)); // GenerateLabel(lab1); // GenerateTriadic(op_beq,0,ap2,makereg(0),make_label(lab2)); // GenerateTriadic(op_subui,0,ap2,ap2,make_immed(1)); // GenerateTriadic(op_lwr,0,ap1,make_string(stmt->label),NULL); // GenerateTriadic(op_bne,0,ap1,makereg(0),make_label(lab1),NULL); // GenerateTriadic(op_not,0,ap1,ap1,NULL); // GenerateTriadic(op_swc,0,ap1,make_string(stmt->label),NULL); // GenerateTriadic(op_bnr,0,make_label(lab1),NULL,NULL); //} //else { // GenerateLabel(lab1); // GenerateTriadic(op_lwr,0,ap1,make_string(stmt->label),NULL); // GenerateTriadic(op_bne,0,ap1,makereg(0),make_label(lab1),NULL); // GenerateTriadic(op_not,0,ap1,ap1,NULL); // GenerateTriadic(op_swc,0,ap1,make_string(stmt->label),NULL); // GenerateTriadic(op_bnr,0,make_label(lab1),NULL,NULL); //} //ReleaseTempRegister(ap1); //ReleaseTempRegister(ap2); //GenerateStatement(stmt->s1); //GenerateDiadic(op_sb,0,makereg(0),make_string(stmt->label)); //if (stmt->exp) { // lab3 = nextlabel++; // GenerateTriadic(op_bra,0,make_label(lab3),NULL,NULL); // GenerateLabel(lab2); // GenerateStatement(stmt->s2); // GenerateLabel(lab3); //} //else { // printf("Warning: The lockfail code is unreachable because spinlock tries are infinite.\r\n"); //} }
void GenerateTry(Statement *stmt) { int lab1,curlab; int oldthrow; char buf[20]; AMODE *ap, *a, *ap2; ENODE *node; SYM *sym; lab1 = nextlabel++; oldthrow = throwlab; throwlab = nextlabel++; if (isTable888|isRaptor64) GenerateDiadic(op_lea,0,makereg(regXLR),make_clabel(throwlab)); else if (isFISA64) { a = make_clabel(throwlab); a->mode = am_immed; FISA64_GenLdi(makereg(regXLR),a,8); } else GenerateDiadic(op_ldi,0,makebreg(CLR),make_clabel(throwlab)); GenerateStatement(stmt->s1); GenerateMonadic(isThor?op_br:op_bra,0,make_clabel(lab1)); GenerateLabel(throwlab); stmt = stmt->s2; // Generate catch statements // r1 holds the value to be assigned to the catch variable // r2 holds the type number while (stmt) { GenMixedSource(stmt); throwlab = oldthrow; curlab = nextlabel++; GenerateLabel(curlab); if (stmt->s2==(Statement *)99999) ; else { if (isRaptor64) GenerateTriadic(op_bnei,0,makereg(2),make_immed((int64_t)stmt->s2),make_clabel(nextlabel)); else if (isFISA64) { ap = GetTempRegister(); GenerateTriadic(op_cmp, 0, ap, makereg(2), make_immed((int64_t)stmt->s2)); GenerateDiadic(op_bne, 0, ap, make_clabel(nextlabel)); ReleaseTempRegister(ap); } else if (isTable888) { GenerateTriadic(op_cmp, 0, makereg(244), makereg(2), make_immed((int64_t)stmt->s2)); GenerateDiadic(op_bne, 0, makereg(244), make_clabel(nextlabel)); } else { // ToDo: fix Thor GenerateTriadic(op_cmpi, 0, make_string("p0"), makereg(2), make_immed((int64_t)stmt->s2)); GeneratePredicatedMonadic(0,PredOp(op_ne),op_br,0,make_clabel(nextlabel)); } } // move the throw expression result in 'r1' into the catch variable. node = (ENODE *)stmt->label; { ap2 = GenerateExpression(node,F_REG|F_MEM,GetNaturalSize(node)); if (ap2->mode==am_reg) GenerateDiadic(op_mov,0,ap2,makereg(1)); else GenStore(makereg(1),ap2,GetNaturalSize(node)); ReleaseTempRegister(ap2); } // GenStore(makereg(1),make_indexed(sym->value.i,regBP),sym->tp->size); GenerateStatement(stmt->s1); stmt=stmt->next; } GenerateLabel(lab1); if (isTable888|isRaptor64) GenerateDiadic(op_lea,0,makereg(regXLR),make_clabel(oldthrow)); else if (isFISA64) { a = make_clabel(oldthrow); a->mode = am_immed; FISA64_GenLdi(makereg(regXLR),a,8); } else GenerateDiadic(op_ldi,0,makebreg(CLR),make_clabel(oldthrow)); }
/* * generate a linear search switch statement. */ void GenerateSwitch(Statement *stmt) { AMODE *ap2; int curlab; int *bf; int nn; int predreg; struct snode *defcase; struct amode *ap; predreg = stmt->predreg; curlab = nextlabel++; defcase = 0; initstack(); if (stmt->exp==NULL) { error(ERR_BAD_SWITCH_EXPR); return; } ap = GenerateExpression(stmt->exp,F_REG,GetNaturalSize(stmt->exp)); // if( ap->preg != 0 ) // GenerateDiadic(op_mov,0,makereg(1),ap); // ReleaseTempRegister(ap); stmt = stmt->s1; while( stmt != NULL ) { if( stmt->s2 ) /* default case ? */ { stmt->label = (int64_t *)curlab; defcase = stmt; } else { bf = (int *)stmt->label; for (nn = bf[0]; nn >= 1; nn--) { if (isFISA64) { ap2 = GetTempRegister(); GenerateTriadic(op_cmpi,0,ap2,ap,make_immed(bf[nn])); GenerateDiadic(op_beq,0,ap2,make_clabel(curlab)); ReleaseTempRegister(ap2); } else if (isTable888) { GenerateTriadic(op_cmp,0,makereg(244),makereg(1),make_immed(bf[nn])); GenerateDiadic(op_beq,0,makereg(244),make_clabel(curlab)); } else if (isRaptor64) { GenerateTriadic(op_beq,0,ap,make_immed(bf[nn]),make_label(curlab)); } else { GenerateTriadic(op_cmp,0,makepred(predreg),ap,make_immed(bf[nn])); GeneratePredicatedMonadic(predreg,PredOp(op_eq),op_br,0,make_clabel(curlab)); } } //GenerateDiadic(op_dw,0,make_label(curlab), make_direct(stmt->label)); stmt->label = (int64_t *)curlab; } if( stmt->s1 != NULL && stmt->next != NULL ) curlab = nextlabel++; stmt = stmt->next; } if( defcase == NULL ) GenerateMonadic(isThor ? op_br : op_bra,0,make_clabel(breaklab)); else GenerateMonadic(isThor ? op_br : op_bra,0,make_clabel((int64_t)defcase->label)); ReleaseTempRegister(ap); }