diff --git a/src/parser.c b/src/parser.c index 9f3cc21..27932c1 100644 --- a/src/parser.c +++ b/src/parser.c @@ -182,13 +182,14 @@ void classifyOpcode(char* opcode, a64inst_instruction *instr, char *operandList[ else { data.regType=1; } + 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.dest = getOperandNumber(operandList[0]); - data.src1 = getOperandNumber(operandList[1]); - data.src2 = getOperandNumber(operandList[2]); + switch (opcode[1]) { // madd case 'a': @@ -214,9 +215,144 @@ void classifyOpcode(char* opcode, a64inst_instruction *instr, char *operandList[ } // arithmlogic else { - + data.DPROpType = 0; + 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; + } + } + } + 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 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], ' '); + 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; + } + } + 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; + // 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; + } + } } - } else { instr->type = a64inst_DPIMMEDIATE; a64inst_DPImmediateData data = instr->data.DPImmediateData;