/* * Execute the ATHROW instruction */ void op_athrow() { // check for null pointer Ref exception = popRef(); if (exception == NULL) { throwException(CORE_THROW_NULL_POINTER); return; } // search for exception handler Ref exceptionType = getRef(exception, OBJECT_TYPE); while (frame != NULL) { // search in current method... if (searchForHandler(exception, exceptionType)) { return; } // ...otherwise pop to previous method frame unlockIfSynchronized(); Ref previous = getRef(frame, FRAME_RETURN_FRAME); setRef(thread, THREAD_FRAME, previous); if (previous != NULL) { loadRegisters(); } } // no handler was found in any frame so exit thread thread = NULL; printf("Illegal State: thread exiting\n"); exit(1); }
/* * This function contains the main interpreter loop. Java * ByteCode instructions are executed one at a time. Before * calling this function the core register should contain * the correct value. */ execute() { // initialise register values printf("Interpreter started\n"); initCollector(); thread = getRef(core, CORE_RUNNING); loadRegisters(); // used to mimic a time slice int maxSize = 50; int count = 0; // execute the next instruction, indefinitely void (*implementation)(); int index; unsigned char bytecode; for (;;) { bytecode = code[pc]; dbgCodes[dbgIndex++] = bytecode; if (dbgIndex == 50) { dbgIndex = 0; } //printf("0x%X\n", bytecode); implementation = distributor[bytecode]; implementation(); count++; // check if another thread needs to be scheduled if (thread == NULL || count >= maxSize) { if (thread != NULL) { saveRegisters(); } scheduleNextThread(); //wakeSleepingThreads(); count = 0; } } }
/* * Read GPIO serial value */ float getSerialData(int num_registers, char* result_string, float rule_height) { unsigned short int idx = 0, value_read = 0, pins_out_water = 0; float pins_mid_level = 0; clockUp(); loadRegisters(); //FIXME: Essa não é a forma correta de dar delay, muito ineficiente __delay_cycles( SLEEP_TIME); clockDown(); unloadRegisters(); for (idx = 0; idx < num_registers; idx++) { //FIXME: Essa não é a forma correta de dar delay, muito ineficiente __delay_cycles( SLEEP_TIME); value_read = readGpio(); pins_out_water += value_read; if (value_read) strcat(result_string, "1"); else strcat(result_string, "0"); clockUp(); //FIXME: Essa não é a forma correta de dar delay, muito ineficiente __delay_cycles( SLEEP_TIME); clockDown(); } pins_mid_level = (MID_LEVEL / RULE_SPACE_PIN); rule_height = ((num_registers - pins_out_water - pins_mid_level) * RULE_SPACE_PIN); return pins_mid_level; }
static void readRoutine(uint8_t num_regs, float* result){ turnOn(); clockUp(); loadRegisters(); //FIXME: add a delay here clockDown(); //FIXME: add a delay here unloadRegisters(); //TODO: code to read pins }
// Generate the code for a method call (save base and return label and call // method). void genMethodCall( FILE* yyout, Method* method, int reg ) { int newLabel_ = newLabel(); int totalSize = method->argumentsSize; int freg = -1; // Save base fprintf( yyout, "\tP(R7+4) = R6;\t// Save base\n" ); // Save return label fprintf( yyout, "\tP(R7) = %i;\t// Save return label\n", newLabel_ ); // Call method fprintf( yyout, "\tGT(%i);\t// Call method\n", method->label ); // Set return label fprintf( yyout, "L %i:\n", newLabel_ ); if(method->returnType){ if(!isFloat(method->returnType)){ // Save return value fprintf( yyout, "\tR%d = %c(R7+%d); // Get return value\n", reg, pointerType(method->returnType), totalSize); }else{ // Save return value fprintf( yyout, "\tRR%d = %c(R7+%d); // Get return value\n", reg, pointerType(method->returnType), totalSize); freg = reg; reg = -1; } totalSize += ((Type*)(method->returnType->info))->size; } // Free arguments memory fprintf( yyout,"\tR7 = R7 + %d;\t// Free memory for arguments and return value\n", totalSize ); // Load the used registers from the stack loadRegisters(yyout, reg, freg); // Print a comment to indicate the method call's end. fprintf( yyout, "\t/* Call to procedure - end */\n\n" ); }
CPURegisterEditor::CPURegisterEditor() { setTitle("CPU Register Editor"); layout.setMargin(5); regALabel.setText("A:"); regAValue.setFont(application->monospaceFont); regXLabel.setText("X:"); regXValue.setFont(application->monospaceFont); regYLabel.setText("Y:"); regYValue.setFont(application->monospaceFont); regSLabel.setText("S:"); regSValue.setFont(application->monospaceFont); regDLabel.setText("D:"); regDValue.setFont(application->monospaceFont); regDBLabel.setText("DB:"); regDBValue.setFont(application->monospaceFont); flagN.setText("N"); flagV.setText("V"); flagM.setText("M"); flagX.setText("X"); flagD.setText("D"); flagI.setText("I"); flagZ.setText("Z"); flagC.setText("C"); flagE.setText("E"); update.setText("Update"); loadRegisters(); layout.append(primaryLayout, {~0, 0}, 5); primaryLayout.append(regALabel, {0, 0}, 5); primaryLayout.append(regAValue, {0, 0}, 5); primaryLayout.append(regXLabel, {0, 0}, 5); primaryLayout.append(regXValue, {0, 0}, 5); primaryLayout.append(regYLabel, {0, 0}, 5); primaryLayout.append(regYValue, {0, 0}, 5); primaryLayout.append(regSLabel, {0, 0}, 5); primaryLayout.append(regSValue, {0, 0}, 5); primaryLayout.append(regDLabel, {0, 0}, 5); primaryLayout.append(regDValue, {0, 0}, 5); primaryLayout.append(regDBLabel, {0, 0}, 5); primaryLayout.append(regDBValue, {0, 0}); layout.append(secondaryLayout, {~0, 0}, 5); secondaryLayout.append(flagN, {0, 0}, 5); secondaryLayout.append(flagV, {0, 0}, 5); secondaryLayout.append(flagM, {0, 0}, 5); secondaryLayout.append(flagX, {0, 0}, 5); secondaryLayout.append(flagD, {0, 0}, 5); secondaryLayout.append(flagI, {0, 0}, 5); secondaryLayout.append(flagZ, {0, 0}, 5); secondaryLayout.append(flagC, {0, 0}); layout.append(tertiaryLayout, {~0, 0}); tertiaryLayout.append(flagE, {0, 0}, 5); tertiaryLayout.append(spacer, {~0, 0}); tertiaryLayout.append(update, {80, 0}); append(layout); update.onActivate = [&] { saveRegisters(); cpuDebugger->updateDisassembly(); setVisible(false); }; setGeometry({{128, 128}, layout.minimumGeometry().size()}); windowManager->append(this, "CPURegisterEditor"); }
/* * Execute the specified method. Return true if the method is executed, * false if it is rolled back for garbage collection. * * target: object for instance methods, class for static * method: the method to be run * offset: amount to increment program counter */ int executeMethod(Ref target, Ref method, int offset) { /* printf("["); if (method[ENTRY_FLAGS].i & ACC_STATIC) { debugString(target[TYPE_NAME].s); } else { debugString(method[ENTRY_OWNER].s[TYPE_NAME].s); } printf("."); debugString(method[ENTRY_NAME].s); debugString(method[ENTRY_DESCRIPTOR].s); printf("]\n"); */ // check for native method Int argcount = getInt(method, METHOD_ARG_COUNT); Int flags = getInt(method, ENTRY_FLAGS); if (flags & ACC_NATIVE) { return executeNativeMethod(target, method, offset); } // if synchronized, acquire the lock Ref lock = NULL; if (flags & ACC_SYNCHRONIZED) { lock = getLock(target); if (lock == NULL) { return FALSE; } // rollback, gc done acquireLock(thread, lock, 0); if (thread == NULL) { return FALSE; } // rollback, wait for lock } // allocate space for new frame Int maxLocals = getInt(method, METHOD_MAX_LOCALS); Int maxStack = getInt(method, METHOD_MAX_STACK); int numWords = FRAME_LOCALS + 2*maxLocals + 2*maxStack; Ref newFrame = allocate(numWords, HEADER_STACK_FRAME); if (newFrame == NULL) { return FALSE; } // rollback, gc done // increment lock count now that instruction can't be rolled back if (flags & ACC_SYNCHRONIZED) { Int count = getInt(lock, LOCK_COUNT); setInt(lock, LOCK_COUNT, count + 1); } // initialise new frame int hash = (char*) newFrame - (char*) core; Ref frameType = getRef(frame, OBJECT_TYPE); setInt(newFrame, OBJECT_HASHCODE, hash); setRef(newFrame, OBJECT_LOCK, lock); setRef(newFrame, OBJECT_TYPE, frameType); setRef(newFrame, FRAME_RETURN_FRAME, frame); setRef(newFrame, FRAME_METHOD, method); setInt(newFrame, FRAME_RETURN_PC, pc + offset); setInt(newFrame, FRAME_PC, 0); setInt(newFrame, FRAME_SP, numWords * 4); // pop arguments off current stack and write to new frame int index = argcount; while (--index >= 0) { if (refOnStack()) { setLocalRef(index, popRef(), newFrame); } else { setLocalInt(index, popInt(), newFrame); } } // point current thread to new frame saveRegisters(); setRef(thread, THREAD_FRAME, newFrame); loadRegisters(); return TRUE; }