DPR arithmetic

This commit is contained in:
GDBWNV 2024-06-12 18:58:54 +01:00
parent 51283891bd
commit 2714830117

View File

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