diff --git a/src/parser.c b/src/parser.c index 27932c1..594d477 100644 --- a/src/parser.c +++ b/src/parser.c @@ -184,12 +184,11 @@ void classifyOpcode(char* opcode, a64inst_instruction *instr, char *operandList[ } data.dest = getOperandNumber(operandList[0]); data.src1 = getOperandNumber(operandList[1]); - data.src2 = getOperandNumber(operandList[2]); // multiply // mul, mneg, madd, msub if (opcode[0] == 'm') { data.DPROpType = 1; - + data.src2 = getOperandNumber(operandList[2]); switch (opcode[1]) { // madd case 'a': @@ -216,76 +215,19 @@ void classifyOpcode(char* opcode, a64inst_instruction *instr, char *operandList[ // arithmlogic else { data.DPROpType = 0; + // overridden when neccesary data.processOpData.arithmLogicData.negShiftedSrc2 = 0; - // logical - data.processOpData.arithmLogicData.type = 0; - // three special cases - if (opcode == 'tst') { - data.dest = ZERO_REGISTER; - data.src1 = getOperandNumber(operandList[0]); - data.src2 = getOperandNumber(operandList[1]); - data.processOp = 3; - if (strlen(operandList) == 3) { - char *split[] = strtok(operandList[2], ' '); - switch (split[1][0]) { - case 'L': - // LSR - if (split[1][2] == 'R') { - data.processOpData.arithmLogicData.shiftType = 1; - } - // LSL - else { - data.processOpData.arithmLogicData.shiftType = 0; - } - break; - // ROR - case 'R': - data.processOpData.arithmLogicData.shiftType = 3; - break; - // ASR - default: - data.processOpData.arithmLogicData.shiftType = 2; - break; - } + // arithmetic + // add, adds + if (opcode[1] == 'd') { + data.processOpData.arithmLogicData.type = 1; + data.src2 = getOperandNumber(operandList[2]); + if (strlen(opcode) == 4) { + data.processOp = 1; } - } - else if (opcode == 'mvn') { - data.dest = getOperandNumber(operandList[0]); - data.src1 = ZERO_REGISTER; - data.src2 = getOperandNumber(operandList[1]); - data.processOp = 1; - data.processOpData.arithmLogicData.negShiftedSrc2 = 1; - if (strlen(operandList) == 3) { - char *split[] = strtok(operandList[2], ' '); - switch (split[1][0]) { - case 'L': - // LSR - if (split[1][2] == 'R') { - data.processOpData.arithmLogicData.shiftType = 1; - } - // LSL - else { - data.processOpData.arithmLogicData.shiftType = 0; - } - break; - // ROR - case 'R': - data.processOpData.arithmLogicData.shiftType = 3; - break; - // ASR - default: - data.processOpData.arithmLogicData.shiftType = 2; - break; - } + else { + data.processOp = 0; } - } - else if (opcode == 'mov') { - data.dest = getOperandNumber(operandList[0]); - data.src1 = ZERO_REGISTER; - data.src2 = getOperandNumber(operandList[1]); - data.processOp = 1; - } - else { // handles shifts if (strlen(operandList) == 4) { char *split[] = strtok(operandList[3], ' '); @@ -310,46 +252,278 @@ void classifyOpcode(char* opcode, a64inst_instruction *instr, char *operandList[ break; } } - switch (opcode[0]) { - // and, ands - case 'a': - // ands - if (strlen(opcode) == 4) { - data.processOp = 3; + } + // cmn + else if (opcode == 'cmn') { + data.dest = ZERO_REGISTER; + data.src1 = getOperandNumber(operandList[0]); + data.src2 = getOperandNumber(operandList[1]); + data.processOpData.arithmLogicData.type = 1; + data.processOp = 1; + // handles shifts + if (strlen(operandList) == 3) { + char *split[] = strtok(operandList[2], ' '); + switch (split[1][0]) { + case 'L': + // LSR + if (split[1][2] == 'R') { + data.processOpData.arithmLogicData.shiftType = 1; + } + // LSL + else { + data.processOpData.arithmLogicData.shiftType = 0; + } + break; + // ROR + case 'R': + data.processOpData.arithmLogicData.shiftType = 3; + break; + // ASR + default: + data.processOpData.arithmLogicData.shiftType = 2; + break; + } + } + } + // sub, subs + else if (opcode[2] == 'b') { + data.src2 = getOperandNumber(operandList[2]); + data.processOpData.arithmLogicData.type = 1; + if (strlen(opcode) == 4) { + data.processOp = 3; + } + else { + data.processOp = 2; + } + // handles shifts + if (strlen(operandList) == 4) { + char *split[] = strtok(operandList[3], ' '); + switch (split[1][0]) { + case 'L': + // LSR + if (split[1][2] == 'R') { + data.processOpData.arithmLogicData.shiftType = 1; + } + // LSL + else { + data.processOpData.arithmLogicData.shiftType = 0; + } + break; + // ROR + case 'R': + data.processOpData.arithmLogicData.shiftType = 3; + break; + // ASR + default: + data.processOpData.arithmLogicData.shiftType = 2; + break; + } + } + } + // cmp + else if (opcode == 'cmp') { + data.dest = ZERO_REGISTER; + data.src1 = getOperandNumber(operandList[0]); + data.src2 = getOperandNumber(operandList[1]); + data.processOpData.arithmLogicData.type = 1; + data.processOp = 3; + // handles shifts + if (strlen(operandList) == 3) { + char *split[] = strtok(operandList[2], ' '); + switch (split[1][0]) { + case 'L': + // LSR + if (split[1][2] == 'R') { + data.processOpData.arithmLogicData.shiftType = 1; + } + // LSL + else { + data.processOpData.arithmLogicData.shiftType = 0; + } + break; + // ROR + case 'R': + data.processOpData.arithmLogicData.shiftType = 3; + break; + // ASR + default: + data.processOpData.arithmLogicData.shiftType = 2; + break; + } + } + } + // neg, negs + else if (opcode[0] == 'n') { + data.src1 = ZERO_REGISTER; + data.src2 = getOperandNumber(operandList[1]); + data.processOpData.arithmLogicData.type = 1; + if (strlen(opcode) == 4) { + data.processOp = 3; + } + else { + data.processOp = 2; + } + // handles shifts + if (strlen(operandList) == 3) { + char *split[] = strtok(operandList[2], ' '); + switch (split[1][0]) { + case 'L': + // LSR + if (split[1][2] == 'R') { + data.processOpData.arithmLogicData.shiftType = 1; + } + // LSL + else { + data.processOpData.arithmLogicData.shiftType = 0; + } + break; + // ROR + case 'R': + data.processOpData.arithmLogicData.shiftType = 3; + break; + // ASR + default: + data.processOpData.arithmLogicData.shiftType = 2; + break; + } + } + } + else { + // logical + data.processOpData.arithmLogicData.type = 0; + // three special cases + if (opcode == 'tst') { + data.dest = ZERO_REGISTER; + data.src1 = getOperandNumber(operandList[0]); + data.src2 = getOperandNumber(operandList[1]); + data.processOp = 3; + if (strlen(operandList) == 3) { + char *split[] = strtok(operandList[2], ' '); + switch (split[1][0]) { + case 'L': + // LSR + if (split[1][2] == 'R') { + data.processOpData.arithmLogicData.shiftType = 1; + } + // LSL + else { + data.processOpData.arithmLogicData.shiftType = 0; + } + break; + // ROR + case 'R': + data.processOpData.arithmLogicData.shiftType = 3; + break; + // ASR + default: + data.processOpData.arithmLogicData.shiftType = 2; + break; } - // and - else { - data.processOp = 0; + } + } + else if (opcode == 'mvn') { + data.dest = getOperandNumber(operandList[0]); + data.src1 = ZERO_REGISTER; + data.src2 = getOperandNumber(operandList[1]); + data.processOp = 1; + data.processOpData.arithmLogicData.negShiftedSrc2 = 1; + if (strlen(operandList) == 3) { + char *split[] = strtok(operandList[2], ' '); + switch (split[1][0]) { + case 'L': + // LSR + if (split[1][2] == 'R') { + data.processOpData.arithmLogicData.shiftType = 1; + } + // LSL + else { + data.processOpData.arithmLogicData.shiftType = 0; + } + break; + // ROR + case 'R': + data.processOpData.arithmLogicData.shiftType = 3; + break; + // ASR + default: + data.processOpData.arithmLogicData.shiftType = 2; + break; } - break; - // bic, bics - case 'b': - data.processOpData.arithmLogicData.negShiftedSrc2 = 1; - // bics - if (strlen(opcode) == 4) { - data.processOp = 3; + } + } + else if (opcode == 'mov') { + data.dest = getOperandNumber(operandList[0]); + data.src1 = ZERO_REGISTER; + data.src2 = getOperandNumber(operandList[1]); + data.processOp = 1; + } + else { + data.src2 = getOperandNumber(operandList[2]); + // handles shifts + if (strlen(operandList) == 4) { + char *split[] = strtok(operandList[3], ' '); + switch (split[1][0]) { + case 'L': + // LSR + if (split[1][2] == 'R') { + data.processOpData.arithmLogicData.shiftType = 1; + } + // LSL + else { + data.processOpData.arithmLogicData.shiftType = 0; + } + break; + // ROR + case 'R': + data.processOpData.arithmLogicData.shiftType = 3; + break; + // ASR + default: + data.processOpData.arithmLogicData.shiftType = 2; + break; } - // bic - else { - data.processOp = 0; - } - break; - // orr, orn - case 'o': - data.processOp = 1; - // orn - if (opcode[2] == 'n') { + } + switch (opcode[0]) { + // and, ands + case 'a': + // ands + if (strlen(opcode) == 4) { + data.processOp = 3; + } + // and + else { + data.processOp = 0; + } + break; + // bic, bics + case 'b': data.processOpData.arithmLogicData.negShiftedSrc2 = 1; - } - break; - // eor, eon - default: - data.processOp = 2; - // eon - if (opcode[2] == 'n') { - data.processOpData.arithmLogicData.negShiftedSrc2 = 1; - } - break; + // bics + if (strlen(opcode) == 4) { + data.processOp = 3; + } + // bic + else { + data.processOp = 0; + } + break; + // orr, orn + case 'o': + data.processOp = 1; + // orn + if (opcode[2] == 'n') { + data.processOpData.arithmLogicData.negShiftedSrc2 = 1; + } + break; + // eor, eon + default: + data.processOp = 2; + // eon + if (opcode[2] == 'n') { + data.processOpData.arithmLogicData.negShiftedSrc2 = 1; + } + break; + } } } } @@ -364,18 +538,23 @@ void classifyOpcode(char* opcode, a64inst_instruction *instr, char *operandList[ data.regType=1; } // arithmetic + // can be overwritten later + data.processOpData.arithmData.shiftImmediate = false; // add, adds if (opcode[1] == 'd') { data.DPIOpType = 0; data.dest = getOperandNumber(operandList[0]); data.processOpData.arithmData.src = getOperandNumber(operandList[1]); data.processOpData.arithmData.immediate = getOperandNumber(operandList[2]); - if (opcode[-1] == 's') { - data.processOpData.arithmData.shiftImmediate = true; + if (strlen(operandList) == 4) { + if (strlen(operandList[3]) == 8) { + data.processOpData.arithmData.shiftImmediate = true; + } + } + if (strlen(opcode) == 4) { data.processOp = 1; } else { - data.processOpData.arithmData.shiftImmediate = false; data.processOp = 0; } } @@ -385,8 +564,12 @@ void classifyOpcode(char* opcode, a64inst_instruction *instr, char *operandList[ data.dest = ZERO_REGISTER; data.processOpData.arithmData.src = getOperandNumber(operandList[0]); data.processOpData.arithmData.immediate = getOperandNumber(operandList[1]); - data.processOpData.arithmData.shiftImmediate = true; data.processOp = 1; + if (strlen(operandList) == 3) { + if (strlen(operandList[2]) == 8) { + data.processOpData.arithmData.shiftImmediate = true; + } + } } // sub, subs else if (opcode[0] == 's') { @@ -394,12 +577,15 @@ void classifyOpcode(char* opcode, a64inst_instruction *instr, char *operandList[ data.dest = getOperandNumber(operandList[0]); data.processOpData.arithmData.src = getOperandNumber(operandList[1]); data.processOpData.arithmData.immediate = getOperandNumber(operandList[2]); + if (strlen(operandList) == 4) { + if (strlen(operandList[3]) == 8) { + data.processOpData.arithmData.shiftImmediate = true; + } + } if (opcode[-1] == 's') { - data.processOpData.arithmData.shiftImmediate = true; data.processOp = 3; } else { - data.processOpData.arithmData.shiftImmediate = false; data.processOp = 2; } } @@ -409,8 +595,12 @@ void classifyOpcode(char* opcode, a64inst_instruction *instr, char *operandList[ data.dest = ZERO_REGISTER; data.processOpData.arithmData.src = getOperandNumber(operandList[0]); data.processOpData.arithmData.immediate = getOperandNumber(operandList[1]); - data.processOpData.arithmData.shiftImmediate = true; data.processOp = 3; + if (strlen(operandList) == 3) { + if (strlen(operandList[2]) == 8) { + data.processOpData.arithmData.shiftImmediate = true; + } + } } // neg, negs else if (opcode[0] == 'n') { @@ -418,12 +608,15 @@ void classifyOpcode(char* opcode, a64inst_instruction *instr, char *operandList[ data.dest = getOperandNumber(operandList[1]); data.processOpData.arithmData.src = ZERO_REGISTER; data.processOpData.arithmData.immediate = getOperandNumber(operandList[2]); + if (strlen(operandList) == 3) { + if (strlen(operandList[2]) == 8) { + data.processOpData.arithmData.shiftImmediate = true; + } + } if (opcode[-1] == 's') { - data.processOpData.arithmData.shiftImmediate = true; data.processOp = 3; } else { - data.processOpData.arithmData.shiftImmediate = false; data.processOp = 2; } }