bool RARProgramAddInstr(RARProgram *prog, uint8_t instruction, bool bytemode) { if (instruction >= RARNumberOfInstructions) return false; if (bytemode && !RARInstructionHasByteMode(instruction)) return false; if (prog->length + 1 >= prog->capacity) { /* in my small file sample, 16 is the value needed most often */ uint32_t newCapacity = prog->capacity ? prog->capacity * 4 : 32; RAROpcode *newCodes = calloc(newCapacity, sizeof(*prog->opcodes)); if (!newCodes) return false; memcpy(newCodes, prog->opcodes, prog->capacity * sizeof(*prog->opcodes)); free(prog->opcodes); prog->opcodes = newCodes; prog->capacity = newCapacity; } memset(&prog->opcodes[prog->length], 0, sizeof(prog->opcodes[prog->length])); prog->opcodes[prog->length].instruction = instruction; if (instruction == RARMovzxInstruction || instruction == RARMovsxInstruction) prog->opcodes[prog->length].bytemode = 2; /* second argument only */ else if (bytemode) prog->opcodes[prog->length].bytemode = (1 | 2); else prog->opcodes[prog->length].bytemode = 0; prog->length++; return true; }
bool PrepareRAROpcodes(RAROpcode *opcodes,int numopcodes) { void **instructionlabels_32,**instructionlabels_8; RunVirtualMachineOrGetLabels(NULL,NULL,0,&instructionlabels_32); instructionlabels_8=&instructionlabels_32[RARNumberOfInstructions]; for(int i=0;i<numopcodes;i++) { if(opcodes[i].instruction>=RARNumberOfInstructions) return false; void **instructionlabels; RARSetterFunction *setterfunctions; RARGetterFunction *getterfunctions; if(opcodes[i].instruction==RARMovsxInstruction||opcodes[i].instruction==RARMovzxInstruction) { instructionlabels=instructionlabels_32; getterfunctions=OperandGetters_8; setterfunctions=OperandSetters_32; } else if(opcodes[i].bytemode) { if(!RARInstructionHasByteMode(opcodes[i].instruction)) return false; instructionlabels=instructionlabels_8; getterfunctions=OperandGetters_8; setterfunctions=OperandSetters_8; } else { instructionlabels=instructionlabels_32; getterfunctions=OperandGetters_32; setterfunctions=OperandSetters_32; } opcodes[i].instructionlabel=instructionlabels[opcodes[i].instruction]; int numoperands=NumberOfRARInstructionOperands(opcodes[i].instruction); if(numoperands>=1) { if(opcodes[i].addressingmode1>=RARNumberOfAddressingModes) return false; opcodes[i].operand1getter=getterfunctions[opcodes[i].addressingmode1]; opcodes[i].operand1setter=setterfunctions[opcodes[i].addressingmode1]; if(opcodes[i].addressingmode1==RARImmediateAddressingMode) { if(RARInstructionWritesFirstOperand(opcodes[i].instruction)) return false; } else if(opcodes[i].addressingmode1==RARAbsoluteAddressingMode) { opcodes[i].value1&=RARProgramMemoryMask; } } if(numoperands==2) { if(opcodes[i].addressingmode2>=RARNumberOfAddressingModes) return false; opcodes[i].operand2getter=getterfunctions[opcodes[i].addressingmode2]; opcodes[i].operand2setter=setterfunctions[opcodes[i].addressingmode2]; if(opcodes[i].addressingmode2==RARImmediateAddressingMode) { if(RARInstructionWritesSecondOperand(opcodes[i].instruction)) return false; } else if(opcodes[i].addressingmode2==RARAbsoluteAddressingMode) { opcodes[i].value2&=RARProgramMemoryMask; } } } return true; }