Fix labels and jumps

This commit is contained in:
2025-02-11 12:29:11 +01:00
parent f8b0307949
commit 0fc4040ad7
4 changed files with 57 additions and 139 deletions

View File

@@ -32,7 +32,7 @@ int lookupLabel(const char *name) {
}
// Add a label to the table
int addLabel(const char *name, int address) {
int addLabel(const char *name, uint32_t address) {
if (labelCount >= MAX_LABELS) {
fprintf(stderr, "Too many labels!\n");
return 1;
@@ -316,139 +316,30 @@ void firstPass(const char *source) {
continue;
strcpy(line, rest);
}
}
// // Parse the mnemonic and operands.
// char mnemonic[32], operand1[64], operand2[64], operand3[64];
// operand1[0] = '\0';
// operand2[0] = '\0';
// int tokenCount = sscanf(line, "%31s %63[^ ] %63[^ ] %63s",
// mnemonic, operand1, operand2, operand3);
//
//
// // Use the mapper to get a base opcode.
// int baseOpcode = getOpcode(mnemonic);
// if (baseOpcode == -1) {
// printf("Unknown instruction: %s\n", mnemonic);
// continue;
// }
//
// int size = CPU_INSTRUCTION_SIZE; // Instruction size in bytes.
// if (baseOpcode == -2) {
// // MOV instruction requires further resolution.
// int resolvedOpcode = resolveMOV(operand1, operand2);
// if (resolvedOpcode == MOV_RN_IMM || resolvedOpcode == MOV_RN_RM) {
// size = 3; // opcode (1) + reg (1) + immediate or register (1)
// } else if (resolvedOpcode == MOV_RN_ADDR || resolvedOpcode == MOV_ADDR_RN) {
// size = 6; // opcode (1) + one operand as register (1) and one 32-bit address (4) [+ padding if needed]
// } else {
// size = 3; // fallback
// }
// } else if (baseOpcode < 0) {
// // Ambiguous instructions that use resolveALU.
// // For JMP and jump-bit instructions, the jump target is in operand1.
// if (baseOpcode == -11) {
// // JMP: if operand1 starts with '+' or '-', it's relative.
// if (operand1[0] == '+' || operand1[0] == '-') {
// // resolve as JMP_REL.
// int resolvedOpcode = resolveALU(baseOpcode, operand1);
// size = 2; // opcode (1) + 1-byte relative offset (1)
// } else {
// int resolvedOpcode = resolveALU(baseOpcode, operand1);
// size = 5; // opcode (1) + 32-bit absolute address (4)
// }
// } else if (baseOpcode == -14 || baseOpcode == -15) {
// // JMPBS or JMPBC (jump if bit set/clear)
// int resolvedOpcode = resolveALU(baseOpcode, operand1);
// if (operand1[0] == 'R' || operand1[0] == 'r')
// size = 7; // opcode (1) + register (1) + bit (1) + 32-bit jump address (4)
// else
// size = 10; // opcode (1) + 32-bit memory address (4) + bit (1) + 32-bit jump address (4)
// } else {
// // For arithmetic ALU instructions and INC/DEC,
// // use operand2 to resolve.
// int resolvedOpcode = resolveALU(baseOpcode, operand2);
// switch (resolvedOpcode) {
// case ADD_RN_RM:
// case SUB_RN_RM:
// case MUL_RN_RM:
// case DIV_RN_RM:
// case MOD_RN_RM:
// case AND_RN_RM:
// case OR_RN_RM:
// case XOR_RN_RM:
// case ADD_RN_IMM:
// case SUB_RN_IMM:
// case MUL_RN_IMM:
// case DIV_RN_IMM:
// case MOD_RN_IMM:
// case AND_RN_IMM:
// case OR_RN_IMM:
// case XOR_RN_IMM:
// size = 3; // opcode (1) + register (1) + reg/immediate (1)
// break;
// case INC_RN:
// case DEC_RN:
// size = 2; // opcode (1) + register (1)
// break;
// case INC_ADDR:
// case DEC_ADDR:
// size = 5; // opcode (1) + 32-bit address (4)
// break;
// default:
// size = 3;
// break;
// }
// }
// } else {
// // Non-ambiguous instructions that have positive opcodes.
// // Use the mapping value (baseOpcode) directly.
// switch (baseOpcode) {
// case NOP:
// case BRK:
// case HLT:
// size = 1;
// break;
// case SWAP:
// case CMP:
// size = 3;
// break;
// case SWAPN:
// case NEG_RN:
// case NOT_RN:
// size = 2;
// break;
// case SHL_RN_IMM:
// case SHR_RN_IMM:
// case SAR_RN_IMM:
// size = 3;
// break;
// case JE:
// case JNE:
// case JG:
// case JL:
// case JGE:
// case JLE:
// case CALL:
// size = 5; // opcode (1) + 32-bit address (4)\n break;
// case RET:
// size = 1;
// break;
// default:
// size = 3;
// break;
// }
// }
// addr += size;
// }
// return addr;
// Parse the mnemonic and operands.
char mnemonic[32], operand1[64], operand2[64], operand3[64];
operand1[0] = '\0';
operand2[0] = '\0';
sscanf(line, "%31s %63[^ ] %63[^ ] %63s",
mnemonic, operand1, operand2, operand3);
// Use the mapper to get a base opcode.
int baseOpcode = getOpcode(mnemonic);
if (baseOpcode == -1) {
printf("Unknown instruction: %s\n", mnemonic);
continue;
}
addr += CPU_INSTRUCTION_SIZE;
}
}
//
// The second pass actually translates the assembly instructions to machine code.
// The machine code is written into the provided buffer. (It must be large enough.)
//
int completePass(const char *source, CPU *cpu, bool erase) {
uint32_t completePass(const char *source, CPU *cpu, bool erase) {
if (erase) {
memset(cpu->memory, 0, sizeof(cpu->memory));
memset(cpu->regs, 0, sizeof(cpu->regs));
@@ -488,8 +379,8 @@ int completePass(const char *source, CPU *cpu, bool erase) {
// Parse mnemonic and up to three operands.
char mnemonic[32], operand1[64], operand2[64], operand3[64];
mnemonic[0] = operand1[0] = operand2[0] = operand3[0] = '\0';
int tokenCount = sscanf(line, "%31s %63[^ ] %63[^ ] %63s",
mnemonic, operand1, operand2, operand3);
sscanf(line, "%31s %63[^ ] %63[^ ] %63s",
mnemonic, operand1, operand2, operand3);
// (Optionally, you might trim each operand individually here.)
@@ -733,5 +624,6 @@ int completePass(const char *source, CPU *cpu, bool erase) {
lineIndex++;
}
cpu->programEnd = addr;
return addr;
}