/* * This is equivalent to cc_interupt() in new_dynarec * */ code_seg_t* Generate_ISR(code_segment_data_t* seg_data) { code_seg_t* code_seg = newSegment(); Instruction_t* newInstruction; Instruction_t* ins = NULL; seg_data->dbgCurrentSegment = code_seg; // need to test if interrupts are enabled (Status Register bit 0) newInstruction = newInstrI(ARM_TST, AL, REG_NOT_USED, REG_STATUS, REG_NOT_USED, 0x01); code_seg->Intermcode = ins = newInstruction; #if USE_INSTRUCTION_COMMENTS sprintf(newInstruction->comment, "Generate_ISR() segment 0x%08x\n", (uint32_t)code_seg); #endif ins = insertCall_To_C(code_seg, ins, AL, (size_t)&cc_interrupt, REG_HOST_STM_EABI); // Return newInstruction = newInstr(ARM_MOV, AL, REG_HOST_PC, REG_NOT_USED, REG_HOST_LR); ADD_LL_NEXT(newInstruction, ins); #if USE_TRANSLATE_DEBUG Translate_Debug(code_seg); #endif Translate_Registers(code_seg); return code_seg; }
code_seg_t* Generate_BranchUnknown(code_segment_data_t* seg_data) { code_seg_t* code_seg = newSegment(); Instruction_t* newInstruction; Instruction_t* ins = NULL; seg_data->dbgCurrentSegment = code_seg; /* Don't think we need this instruction as function branchUnknown() can look * up 'seg_data->dbgCurrentSegment' to: * 1. find/compile the branch target * 2. patch the branch instruction that caused us to end up here. */ newInstruction = newInstr(ARM_MOV, AL, REG_HOST_R0, REG_NOT_USED, REG_HOST_R0); code_seg->Intermcode = ins = newInstruction; #if USE_INSTRUCTION_COMMENTS sprintf(newInstruction->comment, "Generate_BranchUnknown() segment 0x%08x\n", (uint32_t)code_seg); #endif ins = insertCall_To_C(code_seg, ins, AL, (uint32_t)&branchUnknown, REG_HOST_STM_R1_3); // Now jump to the compiled code newInstruction = newInstrI(ARM_SUB, AL, REG_HOST_PC, REG_HOST_R0, REG_NOT_USED, 0); ADD_LL_NEXT(newInstruction, ins); #if 0 && USE_TRANSLATE_DEBUG Translate_Debug(code_seg); #endif Translate_Registers(code_seg); Translate_Literals(code_seg); return code_seg; }
void Translate_BreakAtEndSegment(code_seg_t* codeSegment) { Instruction_t*ins, *new_ins; ins = codeSegment->Intermcode; #if USE_INSTRUCTION_COMMENTS currentTranslation = "Call Debugger_wrapper()"; #endif while (ins->nextInstruction->nextInstruction) { ins = ins->nextInstruction; } new_ins = newInstrPUSH(AL, REG_HOST_STM_ALL); ADD_LL_NEXT(new_ins, ins); new_ins = newInstr(ARM_MOV, AL, REG_HOST_R0, REG_NOT_USED, REG_HOST_SP); ADD_LL_NEXT(new_ins, ins); ins = insertCall_To_C(codeSegment, ins, AL,(uint32_t)Debugger_wrapper, 0); new_ins = newInstrPOP(AL, REG_HOST_STM_ALL); ADD_LL_NEXT(new_ins, ins); }
static void Test_Translate_Registers_emulate_ldr() { code_seg_t* seg = newSegment(); seg->Intermcode = newInstr(ARM_MOV, AL, REG_TEMP_SCRATCH0, REG_NOT_USED, 1U); Translate_Registers(seg); const Instruction_t* const ins_ldr = seg->Intermcode; const Instruction_t* const ins_mov = ins_ldr->nextInstruction; // Register R2 should be loaded from cache assert(ins_ldr->instruction == ARM_LDR); assert(ins_ldr->Reg[INS_RD1].regID > REG_HOST); assert(ins_ldr->offset == 8U); assert(ins_mov->instruction == ARM_MOV); assert(ins_mov->Reg[INS_R2].regID == ins_ldr->Reg[INS_RD1].regID); assert(ins_mov->Reg[INS_RD1].regID == REG_HOST + 0U); assert(ins_mov->nextInstruction == NULL); delSegment(seg); printf("Test_Translate_Registers_emulate_ldr() passed\n"); }
code_seg_t* Generate_MIPS_Trap(code_segment_data_t* seg_data) { code_seg_t* code_seg = newSegment(); Instruction_t* newInstruction; Instruction_t* ins = NULL; seg_data->dbgCurrentSegment = code_seg; // Return newInstruction = newInstr(ARM_MOV, AL, REG_HOST_PC, REG_NOT_USED, REG_HOST_LR); code_seg->Intermcode = ins = newInstruction; #if USE_TRANSLATE_DEBUG Translate_Debug(code_seg); #endif Translate_Registers(code_seg); return code_seg; }
code_seg_t* Generate_CodeStop(code_segment_data_t* seg_data) { code_seg_t* code_seg = newSegment(); Instruction_t* newInstruction; Instruction_t* ins = NULL; seg_data->dbgCurrentSegment = code_seg; newInstruction = newInstrPOP(AL, REG_HOST_STM_EABI2 ); code_seg->Intermcode = ins = newInstruction; newInstruction = newInstrI(ARM_MOV, AL, REG_HOST_R0, REG_NOT_USED, REG_NOT_USED, 0); ADD_LL_NEXT(newInstruction, ins); // Return newInstruction = newInstr(ARM_MOV, AL, REG_HOST_PC, REG_NOT_USED, REG_HOST_LR); ADD_LL_NEXT(newInstruction, ins); Translate_Registers(code_seg); return code_seg; }
static void Test_Translate_Registers_emulate_full() { code_seg_t* seg = newSegment(); seg->Intermcode = newInstr(ARM_MOV, AL, REG_TEMP_SCRATCH0, REG_NOT_USED, 1U); Instruction_t* ins = seg->Intermcode; uint32_t r = 1U; for (r = 1U; r < 32U; r++) { ins->nextInstruction = newInstrI(ARM_MOV, AL, r, REG_NOT_USED, REG_NOT_USED, r); ins = ins->nextInstruction; } ins->nextInstruction = newInstrB(AL, *((uint32_t*)(MMAP_FP_BASE + FUNC_GEN_STOP)), 1); Translate_Registers(seg); Translate_Write(seg); *((volatile int32_t*)MMAP_FP_BASE + REG_COUNT) = -1000; *((uintptr_t*)(MMAP_FP_BASE + RECOMPILED_CODE_START)) = (uintptr_t)seg->ARMEntryPoint; delSegment(seg); run(); for (r = 1U; r < 32U; r++) { printf("r%u = %u\n", r, reg[r]); assert(reg[r] == r); } printf("Test_Translate_Registers_emulate_full() passed\n"); }
/* * Function Called to Begin Running Dynamic compiled code. */ code_seg_t* Generate_CodeStart(code_segment_data_t* seg_data) { code_seg_t* code_seg = newSegment(); Instruction_t* newInstruction; Instruction_t* ins = NULL; seg_data->dbgCurrentSegment = code_seg; code_seg->Type = SEG_START; newInstruction = newInstrPUSH(AL, REG_HOST_STM_EABI2 ); code_seg->Intermcode = ins = newInstruction; regID_t base; int32_t offset; #if defined(TEST_BRANCHING_FORWARD) newInstruction = newInstrI(ARM_MOV, AL, REG_HOST_R0, REG_NOT_USED, REG_NOT_USED, 0); ADD_LL_NEXT(newInstruction, ins); newInstruction = newInstrI(ARM_B, AL, REG_NOT_USED, REG_NOT_USED, REG_NOT_USED, 3); ADD_LL_NEXT(newInstruction, ins); newInstruction = newInstrI(ARM_ADD, AL, REG_HOST_R0, REG_HOST_R0, REG_NOT_USED,0x1); ADD_LL_NEXT(newInstruction, ins); newInstruction = newInstrI(ARM_ADD, AL, REG_HOST_R0, REG_HOST_R0, REG_NOT_USED,0x2); ADD_LL_NEXT(newInstruction, ins); newInstruction = newInstrI(ARM_ADD, AL, REG_HOST_R0, REG_HOST_R0, REG_NOT_USED,0x4); ADD_LL_NEXT(newInstruction, ins); newInstruction = newInstrI(ARM_ADD, AL, REG_HOST_R0, REG_HOST_R0, REG_NOT_USED,0x8); ADD_LL_NEXT(newInstruction, ins); newInstruction = newInstrI(ARM_ADD, AL, REG_HOST_R0, REG_HOST_R0, REG_NOT_USED,0x10); ADD_LL_NEXT(newInstruction, ins); newInstruction = newInstrI(ARM_ADD, AL, REG_HOST_R0, REG_HOST_R0, REG_NOT_USED,0x20); ADD_LL_NEXT(newInstruction, ins); newInstruction = newInstrI(ARM_ADD, AL, REG_HOST_R0, REG_HOST_R0, REG_NOT_USED,0x40); ADD_LL_NEXT(newInstruction, ins); // return back to debugger newInstruction = newInstr(ARM_MOV, AL, REG_HOST_PC, REG_NOT_USED, REG_HOST_LR); ADD_LL_NEXT(newInstruction, ins); #elif defined(TEST_BRANCHING_BACKWARD) // Jump forwards to the Landing Pad newInstruction = newInstrI(ARM_MOV, AL, REG_HOST_R0, REG_NOT_USED, REG_NOT_USED, 0); ADD_LL_NEXT(newInstruction, ins); newInstruction = newInstrI(ARM_B, AL, REG_NOT_USED, REG_NOT_USED, REG_NOT_USED, 10); ADD_LL_NEXT(newInstruction, ins); newInstruction = newInstrI(ARM_ADD, AL, REG_HOST_R0, REG_HOST_R0, REG_NOT_USED,0x1); ADD_LL_NEXT(newInstruction, ins); newInstruction = newInstrI(ARM_ADD, AL, REG_HOST_R0, REG_HOST_R0, REG_NOT_USED,0x2); ADD_LL_NEXT(newInstruction, ins); newInstruction = newInstrI(ARM_ADD, AL, REG_HOST_R0, REG_HOST_R0, REG_NOT_USED,0x4); ADD_LL_NEXT(newInstruction, ins); newInstruction = newInstrI(ARM_ADD, AL, REG_HOST_R0, REG_HOST_R0, REG_NOT_USED,0x8); ADD_LL_NEXT(newInstruction, ins); newInstruction = newInstrI(ARM_ADD, AL, REG_HOST_R0, REG_HOST_R0, REG_NOT_USED,0x10); ADD_LL_NEXT(newInstruction, ins); newInstruction = newInstrI(ARM_ADD, AL, REG_HOST_R0, REG_HOST_R0, REG_NOT_USED,0x20); ADD_LL_NEXT(newInstruction, ins); newInstruction = newInstrI(ARM_ADD, AL, REG_HOST_R0, REG_HOST_R0, REG_NOT_USED,0x40); ADD_LL_NEXT(newInstruction, ins); // return back to debugger newInstruction = newInstr(ARM_MOV, AL, REG_HOST_PC, REG_NOT_USED, REG_HOST_LR); ADD_LL_NEXT(newInstruction, ins); // Landing pad newInstruction = newInstrI(ARM_ADD, AL, REG_HOST_R0, REG_HOST_R0, REG_NOT_USED,0); ADD_LL_NEXT(newInstruction, ins); newInstruction = newInstrI(ARM_ADD, AL, REG_HOST_R0, REG_HOST_R0, REG_NOT_USED,0); ADD_LL_NEXT(newInstruction, ins); newInstruction = newInstrI(ARM_ADD, AL, REG_HOST_R0, REG_HOST_R0, REG_NOT_USED,0); ADD_LL_NEXT(newInstruction, ins); newInstruction = newInstrI(ARM_ADD, AL, REG_HOST_R0, REG_HOST_R0, REG_NOT_USED,0); ADD_LL_NEXT(newInstruction, ins); // Now jump backwards newInstruction = newInstrI(ARM_B, AL, REG_NOT_USED, REG_NOT_USED, REG_NOT_USED, -10); ADD_LL_NEXT(newInstruction, ins); #elif defined(TEST_BRANCH_TO_C) newInstruction = newInstrI(ARM_MOV, AL, REG_HOST_R0, REG_NOT_USED, REG_NOT_USED, 0); ADD_LL_NEXT(newInstruction, ins); addLiteral(code_seg, &base, &offset,(uint32_t)&test_callCode); assert(base == REG_HOST_PC); newInstruction = newInstrI(ARM_LDR_LIT, AL, REG_HOST_R1, REG_NOT_USED, base, offset); ADD_LL_NEXT(newInstruction, ins); newInstruction = newInstr(ARM_MOV, AL, REG_HOST_LR, REG_NOT_USED, REG_HOST_PC); ADD_LL_NEXT(newInstruction, ins); newInstruction = newInstr(ARM_MOV, AL, REG_HOST_PC, REG_NOT_USED, REG_HOST_R1); ADD_LL_NEXT(newInstruction, ins); newInstruction = newInstrPOP(AL, REG_HOST_STM_EABI2 ); ADD_LL_NEXT(newInstruction, ins); // Return back to Debugger newInstruction = newInstr(ARM_MOV, AL, REG_HOST_PC, REG_NOT_USED, REG_HOST_LR); ADD_LL_NEXT(newInstruction, ins); #elif defined(TEST_LITERAL) // Test Literal loading addLiteral(code_seg, &base, &offset,(uint32_t)MMAP_FP_BASE); assert(base == REG_HOST_PC); newInstruction = newInstrI(ARM_LDR_LIT, AL, REG_HOST_R0, REG_NOT_USED, base, offset); ADD_LL_NEXT(newInstruction, ins); // return back to debugger newInstruction = newInstr(ARM_MOV, AL, REG_HOST_PC, REG_NOT_USED, REG_HOST_LR); ADD_LL_NEXT(newInstruction, ins); #elif defined(TEST_ROR) newInstruction = newInstrI(ARM_MOV, AL, REG_HOST_R0, REG_NOT_USED, REG_NOT_USED, 0x00138000); ADD_LL_NEXT(newInstruction, ins); newInstruction = newInstr(ARM_MOV, AL, REG_HOST_PC, REG_NOT_USED, REG_HOST_LR); ADD_LL_NEXT(newInstruction, ins); #else addLiteral(code_seg, &base, &offset,(uint32_t)MMAP_FP_BASE); assert(base == REG_HOST_PC); // setup the HOST_FP newInstruction = newInstrI(ARM_LDR_LIT, AL, REG_EMU_FP, REG_NOT_USED, base, offset); ADD_LL_NEXT(newInstruction, ins); // start executing recompiled code newInstruction = newInstrI(ARM_LDR, AL, REG_HOST_PC, REG_NOT_USED, REG_EMU_FP, RECOMPILED_CODE_START); ADD_LL_NEXT(newInstruction, ins); #endif Translate_Registers(code_seg); Translate_Literals(code_seg); return code_seg; }
struct llmne_instr InstrParse(TokenCtx* ctx) { /* TODO adds STORE,PRINT,SET and fix the multiplce action instruction and the address calculation */ int i, offset = 0; char* ptr = NULL; if(searchSymbols("$$")) (searchSymbols("$$"))->offset = nline - 1; int size = sizeof(instruction_set) / sizeof(struct lxs_mne); if( !strcmp( ctx->instr, "DISPLAY" ) ) { if(!strcmp(ctx->args[0],"INT")) offset = 0; else if(!strcmp(ctx->args[0],"HEX")) offset = 1; else if(!strcmp(ctx->args[0],"BIN")) offset = 2; else if(!strcmp(ctx->args[0],"CHAR")) offset = 3; else if(!strcmp(ctx->args[0],"STRING")) offset = 4; else offset = 0; return newInstr(ctx, 34, offset); } for(i = 0;i < size;i++) { if( !strcmp( ctx->instr, instruction_set[i].mne ) ) { if( instruction_set[i].opcode ) { if((ptr = strchr(ctx->args[0],'+'))) { offset = atoi( ptr + 1); ptr[0] = '\0'; } if(searchSymbols(ctx->args[0])) return newInstr(ctx, instruction_set[i].instr, (searchSymbols(ctx->args[0]))->offset + offset); else return newInstr(ctx, instruction_set[i].instr , atoi(ctx->args[0])); } else return newInstr(ctx, instruction_set[i].instr , instruction_set[i].instr); } } ptr = strdup(ctx->instr); int argc = ctx->argc; char** args = malloc( argc * sizeof(char**) ); for(i = 0;i < argc;i++) args[i] = trim(ctx->args[i]); return (struct llmne_instr) { "VAR" ,{ "VAR", ptr , args , argc }, 0, 0, atoi(ptr) };
void Read(VMachine** pvm) { VMachine*vm = *pvm; int i=0; SymDesc* s= start; while(s) { if (s->cont) vm->str[i] = newStr(s->cont); else vm->str[i] = newStr2(); s->idx = i ++; s = s->next; } vm->ninstr = Len(intcode); vm->instr = (Instr*)malloc(vm->ninstr * sizeof(Instr)); IntInstr *cinstr = intcode; for (i=0;i<vm->ninstr;i++) { switch (cinstr->opcode) { case OP_NOP : vm->instr[i] = newInstr(OP_NOP,0); break; case OP_PUSH : vm->instr[i] = newInstr(OP_PUSH,cinstr->str->idx);break; case OP_GETTOP : vm->instr[i] = newInstr(OP_GETTOP,cinstr->str->idx); break; case OP_DISCARD : vm->instr[i] = newInstr(OP_DISCARD,0);break; case OP_PRINT : vm->instr[i] = newInstr(OP_PRINT,0); break; case OP_INPUT : vm->instr[i] = newInstr(OP_INPUT,cinstr->str->idx); break; case OP_JMP : vm->instr[i] = newInstr(OP_JMP,cinstr->target->n - i); break; case OP_JMPF : vm->instr[i] = newInstr(OP_JMPF,cinstr->target->n - i); break; case OP_STR_EQUAL : vm->instr[i] = newInstr(OP_STR_EQUAL,0);break; case OP_BOOL_EQUAL : vm->instr[i] = newInstr(OP_BOOL_EQUAL,0);break; case OP_CONCAT : vm->instr[i] = newInstr(OP_CONCAT,0); break; case OP_BOOL2STR : vm->instr[i] = newInstr(OP_BOOL2STR,0);break; case JUMPTARGET : vm->instr[i] = newInstr(OP_NOP,0);break; } cinstr = cinstr->next; } }
struct llmne_instr InstrParse(TokenCtx* ctx) { /* TODO adds STORE,PRINT,SET and fix the multiplce action instruction and the address calculation */ int offset = 0; char* ptr = NULL; if(searchSymbols("$$")) (searchSymbols("$$"))->offset = nline - 1; if(!strcmp(ctx->instr,"READ")) { if((ptr = strchr(ctx->args[0],'+'))) { offset = atoi(ptr+1); ptr[0] = '\0'; } if(searchSymbols(ctx->args[0])) return newInstr(ctx,10,(searchSymbols(ctx->args[0]))->offset + offset); else return newInstr(ctx,10,atoi(ctx->args[0])); } else if (!strcmp(ctx->instr,"WRITE")) { if((ptr = strchr(ctx->args[0],'+'))) { offset = atoi(ptr+1); ptr[0] = '\0'; } if(searchSymbols(ctx->args[0])) return newInstr(ctx,11,(searchSymbols(ctx->args[0]))->offset + offset); else return newInstr(ctx,11,atoi(ctx->args[0])); } else if (!strcmp(ctx->instr,"POP")) { if((ptr = strchr(ctx->args[0],'+'))) { offset = atoi(ptr+1); ptr[0] = '\0'; } if(searchSymbols(ctx->args[0])) return newInstr(ctx,12,(searchSymbols(ctx->args[0]))->offset + offset); else return newInstr(ctx,12,atoi(ctx->args[0])); } else if (!strcmp(ctx->instr,"PUSH")) { if((ptr = strchr(ctx->args[0],'+'))) { offset = atoi(ptr+1); ptr[0] = '\0'; } if(searchSymbols(ctx->args[0])) return newInstr(ctx,13,(searchSymbols(ctx->args[0]))->offset + offset); else return newInstr(ctx,13,atoi(ctx->args[0])); } else if (!strcmp(ctx->instr,"ADD")) { if((ptr = strchr(ctx->args[0],'+'))) { offset = atoi(ptr+1); ptr[0] = '\0'; } if(searchSymbols(ctx->args[0])) return newInstr(ctx,14,(searchSymbols(ctx->args[0]))->offset + offset); else return newInstr(ctx,14,atoi(ctx->args[0])); } else if (!strcmp(ctx->instr,"SUB")) { if((ptr = strchr(ctx->args[0],'+'))) { offset = atoi(ptr+1); ptr[0] = '\0'; } if(searchSymbols(ctx->args[0])) return newInstr(ctx,15,(searchSymbols(ctx->args[0]))->offset + offset); else return newInstr(ctx,15,atoi(ctx->args[0])); } else if (!strcmp(ctx->instr,"MUL")) { if((ptr = strchr(ctx->args[0],'+'))) { offset = atoi(ptr+1); ptr[0] = '\0'; } if(searchSymbols(ctx->args[0])) return newInstr(ctx,16,(searchSymbols(ctx->args[0]))->offset + offset); else return newInstr(ctx,16,atoi(ctx->args[0])); } else if (!strcmp(ctx->instr,"DIV")) { if((ptr = strchr(ctx->args[0],'+'))) { offset = atoi(ptr+1); ptr[0] = '\0'; } if(searchSymbols(ctx->args[0])) return newInstr(ctx,17,(searchSymbols(ctx->args[0]))->offset + offset); else return newInstr(ctx,17,atoi(ctx->args[0])); } else if (!strcmp(ctx->instr,"MOD")) { if((ptr = strchr(ctx->args[0],'+'))) { offset = atoi(ptr+1); ptr[0] = '\0'; } if(searchSymbols(ctx->args[0])) return newInstr(ctx,18,(searchSymbols(ctx->args[0]))->offset + offset); else return newInstr(ctx,18,atoi(ctx->args[0])); } else if (!strcmp(ctx->instr,"AND")) { if((ptr = strchr(ctx->args[0],'+'))) { offset = atoi(ptr+1); ptr[0] = '\0'; } if(searchSymbols(ctx->args[0])) return newInstr(ctx,19,(searchSymbols(ctx->args[0]))->offset + offset); else return newInstr(ctx,19,atoi(ctx->args[0])); } else if (!strcmp(ctx->instr,"OR")) { if((ptr = strchr(ctx->args[0],'+'))) { offset = atoi(ptr+1); ptr[0] = '\0'; } if(searchSymbols(ctx->args[0])) return newInstr(ctx,20,(searchSymbols(ctx->args[0]))->offset + offset); else return newInstr(ctx,20,atoi(ctx->args[0])); } else if (!strcmp(ctx->instr,"XOR")) { if((ptr = strchr(ctx->args[0],'+'))) { offset = atoi(ptr+1); ptr[0] = '\0'; } if(searchSymbols(ctx->args[0])) return newInstr(ctx,21,(searchSymbols(ctx->args[0]))->offset + offset); else return newInstr(ctx,21,atoi(ctx->args[0])); } else if (!strcmp(ctx->instr,"NOT")) { if((ptr = strchr(ctx->args[0],'+'))) { offset = atoi(ptr+1); ptr[0] = '\0'; } if(searchSymbols(ctx->args[0])) return newInstr(ctx,22,(searchSymbols(ctx->args[0]))->offset + offset); else return newInstr(ctx,22,atoi(ctx->args[0])); } else if (!strcmp(ctx->instr,"SHL")) { if((ptr = strchr(ctx->args[0],'+'))) { offset = atoi(ptr+1); ptr[0] = '\0'; } if(searchSymbols(ctx->args[0])) return newInstr(ctx,23,(searchSymbols(ctx->args[0]))->offset + offset); else return newInstr(ctx,23,atoi(ctx->args[0])); } else if (!strcmp(ctx->instr,"SHR")) { if((ptr = strchr(ctx->args[0],'+'))) { offset = atoi(ptr+1); ptr[0] = '\0'; } if(searchSymbols(ctx->args[0])) return newInstr(ctx,24,(searchSymbols(ctx->args[0]))->offset + offset); else return newInstr(ctx,24,atoi(ctx->args[0])); } else if (!strcmp(ctx->instr,"DEL")) { if((ptr = strchr(ctx->args[0],'+'))) { offset = atoi(ptr+1); ptr[0] = '\0'; } if(searchSymbols(ctx->args[0])) return newInstr(ctx,25,(searchSymbols(ctx->args[0]))->offset + offset); else return newInstr(ctx,25,atoi(ctx->args[0])); } else if (!strcmp(ctx->instr,"NOP")) { return newInstr(ctx,26,26); } else if (!strcmp(ctx->instr,"JMP")) { if((ptr = strchr(ctx->args[0],'+'))) { offset = atoi(ptr+1); ptr[0] = '\0'; } if(searchSymbols(ctx->args[0])) return newInstr(ctx,27,(searchSymbols(ctx->args[0]))->offset + offset); else return newInstr(ctx,27,atoi(ctx->args[0])); } else if (!strcmp(ctx->instr,"CMP")) { if((ptr = strchr(ctx->args[0],'+'))) { offset = atoi(ptr+1); ptr[0] = '\0'; } if(searchSymbols(ctx->args[0])) return newInstr(ctx,28,(searchSymbols(ctx->args[0]))->offset + offset); else return newInstr(ctx,28,atoi(ctx->args[0])); } else if (!strcmp(ctx->instr,"JN")) { if((ptr = strchr(ctx->args[0],'+'))) { offset = atoi(ptr+1); ptr[0] = '\0'; } if(searchSymbols(ctx->args[0])) return newInstr(ctx,29,(searchSymbols(ctx->args[0]))->offset + offset); else return newInstr(ctx,29,atoi(ctx->args[0])); } else if (!strcmp(ctx->instr,"JZ")) { if((ptr = strchr(ctx->args[0],'+'))) { offset = atoi(ptr+1); ptr[0] = '\0'; } if(searchSymbols(ctx->args[0])) return newInstr(ctx,30,(searchSymbols(ctx->args[0]))->offset + offset); else return newInstr(ctx,30,atoi(ctx->args[0])); } else if (!strcmp(ctx->instr,"JM")) { if((ptr = strchr(ctx->args[0],'+'))) { offset = atoi(ptr+1); ptr[0] = '\0'; } if(searchSymbols(ctx->args[0])) return newInstr(ctx,31,(searchSymbols(ctx->args[0]))->offset + offset); else return newInstr(ctx,31,atoi(ctx->args[0])); } else if (!strcmp(ctx->instr,"JG")) { if((ptr = strchr(ctx->args[0],'+'))) { offset = atoi(ptr+1); ptr[0] = '\0'; } if(searchSymbols(ctx->args[0])) return newInstr(ctx,32,(searchSymbols(ctx->args[0]))->offset + offset); else return newInstr(ctx,32,atoi(ctx->args[0])); } else if (!strcmp(ctx->instr,"EXIT")) { if((ptr = strchr(ctx->args[0],'+'))) { offset = atoi(ptr+1); ptr[0] = '\0'; } if(searchSymbols(ctx->args[0])) return newInstr(ctx,33,(searchSymbols(ctx->args[0]))->offset + offset); else return newInstr(ctx,33,atoi(ctx->args[0])); } else if (!strcmp(ctx->instr,"DISPLAY")) { if(!strcmp(ctx->args[0],"INT")) offset = 0; else if(!strcmp(ctx->args[0],"HEX")) offset = 1; else if(!strcmp(ctx->args[0],"BIN")) offset = 2; else if(!strcmp(ctx->args[0],"CHAR")) offset = 3; else if(!strcmp(ctx->args[0],"STRING")) offset = 4; else offset = 0; return newInstr(ctx,34,offset); } else if (!strcmp(ctx->instr,"INC")) { if((ptr = strchr(ctx->args[0],'+'))) { offset = atoi(ptr+1); ptr[0] = '\0'; } if(searchSymbols(ctx->args[0])) return newInstr(ctx,35,(searchSymbols(ctx->args[0]))->offset + offset); else return newInstr(ctx,35,atoi(ctx->args[0])); } else if (!strcmp(ctx->instr,"DEC")) { if((ptr = strchr(ctx->args[0],'+'))) { offset = atoi(ptr+1); ptr[0] = '\0'; } if(searchSymbols(ctx->args[0])) return newInstr(ctx,36,(searchSymbols(ctx->args[0]))->offset + offset); else return newInstr(ctx,36,atoi(ctx->args[0])); } else if (!strcmp(ctx->instr,"CALL")) { if((ptr = strchr(ctx->args[0],'+'))) { offset = atoi(ptr+1); ptr[0] = '\0'; } if(searchSymbols(ctx->args[0])) return newInstr(ctx,37,(searchSymbols(ctx->args[0]))->offset + offset); else return newInstr(ctx,37,atoi(ctx->args[0])); } else if (!strcmp(ctx->instr,"RET")) { return newInstr(ctx,38,00); } else if (!strcmp(ctx->instr,"STPUSH")) { if((ptr = strchr(ctx->args[0],'+'))) { offset = atoi(ptr+1); ptr[0] = '\0'; } if(searchSymbols(ctx->args[0])) return newInstr(ctx,39,(searchSymbols(ctx->args[0]))->offset + offset); else return newInstr(ctx,39,atoi(ctx->args[0])); } else if (!strcmp(ctx->instr,"STPOP")) { if((ptr = strchr(ctx->args[0],'+'))) { offset = atoi(ptr+1); ptr[0] = '\0'; } if(searchSymbols(ctx->args[0])) return newInstr(ctx,40,(searchSymbols(ctx->args[0]))->offset + offset); else return newInstr(ctx,40,atoi(ctx->args[0])); } else if (!strcmp(ctx->instr,"ADDSP")) { return newInstr(ctx,41,atoi(ctx->args[0])); } else if (!strcmp(ctx->instr,"SUBSP")) { return newInstr(ctx,42,atoi(ctx->args[0])); } ptr = strdup(ctx->instr); int i; int argc = ctx->argc; char** args = malloc( argc * sizeof(char**) ); for(i = 0;i < argc;i++) args[i] = trim(ctx->args[i]); return (struct llmne_instr) { "VAR" ,{ "VAR", ptr , args , argc }, 0, 0, atoi(ptr) };
void Translate_Debug(code_seg_t* codeSegment) { Instruction_t*ins; Instruction_t*new_ins; ins = codeSegment->Intermcode; #if USE_BREAKPOINTS || USE_TRANSLATE_DEBUG_SET_CURRENT_SEG #if USE_INSTRUCTION_COMMENTS currentTranslation = "Debug - Get CodeSegment"; #endif regID_t base; int32_t offset; //TODO Nasty global segmentData! //load current segment Address addLiteral(codeSegment, &base, &offset, (uint32_t)codeSegment); codeSegment->Intermcode = new_ins = newInstrI(ARM_LDR_LIT, AL, REG_TEMP_SCRATCH0, REG_NOT_USED, base, offset); new_ins->nextInstruction = ins; ins = new_ins; #endif #if USE_BREAKPOINTS #if USE_INSTRUCTION_COMMENTS currentTranslation = "Debug - Service Breakpoints"; #endif new_ins = newInstrPUSH(AL, REG_HOST_STM_ALL); ADD_LL_NEXT(new_ins, ins); new_ins = newInstr(ARM_MOV, AL, REG_HOST_R1, REG_NOT_USED, REG_HOST_SP); ADD_LL_NEXT(new_ins, ins); ins = insertCall_To_C(codeSegment, ins, AL,(uint32_t)ServiceBreakPoint, 0); new_ins = newInstrPOP(AL, REG_HOST_STM_ALL); ADD_LL_NEXT(new_ins, ins); #endif #if USE_INSTRUCTION_COMMENTS currentTranslation = "Debug - Load Segment ID"; #endif #if USE_TRANSLATE_DEBUG_SET_CURRENT_SEG //load segmentData->dbgCurrentSegment address addLiteral(codeSegment, &base, &offset, (uint32_t)&segmentData.dbgCurrentSegment); new_ins = newInstrI(ARM_LDR_LIT, AL, REG_TEMP_SCRATCH1, REG_NOT_USED, base, offset); ADD_LL_NEXT(new_ins, ins); #if USE_INSTRUCTION_COMMENTS currentTranslation = "Debug - Store Segment ID"; #endif #endif //store new_ins = newInstrI(ARM_STR, AL, REG_NOT_USED, REG_TEMP_SCRATCH0, REG_TEMP_SCRATCH1, 0); ADD_LL_NEXT(new_ins, ins); #if USE_TRANSLATE_DEBUG_PRINT_SEGMENT #if USE_INSTRUCTION_COMMENTS currentTranslation = "Call DebugRuntimePrintSegment()"; #endif ins = insertCall_To_C(codeSegment, ins, AL,(uint32_t)DebugRuntimePrintSegment, 0); #endif #if USE_TRANSLATE_DEBUG_PRINT_REGISTERS_ON_ENTRY #if USE_INSTRUCTION_COMMENTS currentTranslation = "Call DebugRuntimePrintMIPS()"; #endif { static code_seg_t* lastSeg = NULL; if (lastSeg != codeSegment) { ins = insertCall_To_C(codeSegment, ins, AL,(uint32_t)DebugRuntimePrintMIPS, 0); lastSeg = codeSegment; } } #endif #if USE_INSTRUCTION_COMMENTS currentTranslation = "Debug - Instruction count"; #endif #if USE_TRANSLATE_DEBUG_LINE_NUMBERS int x=0; while (ins->nextInstruction->nextInstruction) { new_ins = newInstrI(ARM_MOV, AL, REG_EMU_DEBUG1, REG_NOT_USED, REG_NOT_USED, x); ADD_LL_NEXT(new_ins, ins); x++; ins = ins->nextInstruction; } #endif }