Add handling of all aliases. Add Shift Utility Function

This commit is contained in:
sBubshait 2024-06-14 02:00:10 +01:00
parent 0815d5b6f6
commit f3e1c1f150

View File

@ -25,7 +25,8 @@ static const char *ARITHMETIC_OPCODES[] = {"add", "adds", "sub", "subs"};
static const char *MULTIPLY_OPCODES[] = {"mul", "madd", "msub", "mneg"};
static const char *SHIFT_TYPE_OPCODES[] = {"lsl", "lsr", "asr", "ror"};
static const char *LOGIC_OPCODES[] = {"and", "ands", "bic", "bics", "eor", "eon", "orr", "orn"};
//static const char *ALIASES[] = {"cmp", "cmn", "neg", "negs", "tst", "mvn", "mov", "mul", "mneg"};
static const char *ALIAS_OPCODES[] = {"cmp", "cmn", "neg", "negs", "tst", "mvn", "mov"};
static char *ALIAS_TARGET_OPCODES[] = {"subs", "adds", "sub", "subs", "ands", "orn", "orr"};
a64inst_instruction *parse(char **asmLines, int lineCount) {
a64inst_instruction *instructions = malloc(sizeof(a64inst_instruction) * lineCount);
@ -64,6 +65,25 @@ static int indexStringIn(char *str, const char *arr[], int arrSize) {
return -1;
}
typedef struct {
int type;
int immediate;
} ShiftData;
static ShiftData *parseShift(char *shift) {
char buffer[100];
strcpy(buffer, shift);
char *shiftType = strtok(buffer, " ");
char *shiftAmount = strtok(NULL, " ");
ShiftData *data = malloc(sizeof(ShiftData));
data->type = indexStringIn(shiftType, SHIFT_TYPE_OPCODES, 4);
while (*shiftAmount == ' ' || *shiftAmount == '#') {
shiftAmount++;
}
data->immediate = atoi(shiftAmount);
return data;
}
int isOperandRegister(char regStartChar) {
return((regStartChar == 'x') || (regStartChar == 'w'));
}
@ -74,7 +94,52 @@ int classifyDPInst(char *operandList[]){
isOperandRegister(operandList[3][0]));
}
void classifyOpcode(char* opcode, a64inst_instruction *instr, char *tokens[], int tokensCount){
void classifyAlias(char *opcode, a64inst_instruction *instr, char *tokens[], int *tokensCount) {
int aliasIndex = indexStringIn(opcode, ALIAS_OPCODES, 9);
if (aliasIndex != -1) {
// The instruction is one of the aliases, convert into the target.
char *opcode = ALIAS_TARGET_OPCODES[aliasIndex];
// To correctly encode the zero register, which is either w31 or x31.
char *zeroReg = malloc(5 * sizeof(char));
*zeroReg = *tokens[1];
strcat(zeroReg, "31");
switch(aliasIndex) {
case 0: // cmp -> subs rzr, rn, <op2>
case 1: // cmn -> adds rzr, rn, <op2>
case 4: // tst -> ands rzr, rn, <op2>
// Convert from [instr] REG, <op2> to [instr] RZR, REG, <op2>
tokens[0] = opcode;
tokens[4] = tokens[3];
tokens[3] = tokens[2];
tokens[2] = tokens[1];
tokens[1] = zeroReg;
(*tokensCount)++;
break;
case 2: // neg -> subs rd, rzr, <op2>
case 3: // negs -> subs rd, rzr, <op2>
case 5: // mvn -> orn rd, rzr, <op2>
case 6: // mov -> orr rd, rzr, rm
tokens[0] = opcode;
tokens[4] = tokens[3];
tokens[3] = tokens[2];
tokens[2] = zeroReg;
(*tokensCount)++;
break;
default:
break;
}
}
}
void classifyOpcode(char* opcode, a64inst_instruction *instr, char *tokens[], int *tokensCount){
classifyAlias(opcode, instr, tokens, tokensCount);
if (isStringIn(opcode, BRANCH_OPCODES, 9)) {
instr->type = a64inst_BRANCH;
@ -132,7 +197,7 @@ void parse_instruction(char asmLine[], a64inst_instruction *instr) {
} else {
// Instruction
classifyOpcode(opcode, instr, tokens, tokensCount);
classifyOpcode(opcode, instr, tokens, &tokensCount);
switch(instr->type){
case a64inst_BRANCH:
@ -296,12 +361,8 @@ void parseDPImmediate(a64inst_instruction *inst, char *tokens[], int tokensCount
data->processOp = indexStringIn(tokens[0], WIDE_MOV_OPCODES, 4);
data->processOpData.wideMovData.immediate = getOperandNumber(tokens[2]);
if (tokensCount >= 4) {
int numTokens = 0;
char **shiftOperands = tokenise(tokens[3], &numTokens);
int shiftAmount = getOperandNumber(shiftOperands[1]);
if (shiftAmount > 0) {
data->processOpData.wideMovData.shiftScalar = 12;
}
ShiftData shData = *parseShift(tokens[3]);
data->processOpData.wideMovData.shiftScalar = shData.immediate;
}
} else {
@ -311,10 +372,8 @@ void parseDPImmediate(a64inst_instruction *inst, char *tokens[], int tokensCount
data->processOpData.arithmData.immediate = getOperandNumber(tokens[3]);
if (tokensCount >= 5) {
int numTokens = 0;
char **shiftOperands = tokenise(tokens[4], &numTokens);
int shiftAmount = getOperandNumber(shiftOperands[1]);
if (shiftAmount > 0) {
ShiftData shData = *parseShift(tokens[4]);
if (shData.immediate > 0) {
data->processOpData.arithmData.shiftImmediate = true;
}
}
@ -340,6 +399,7 @@ void parseDPRegister(a64inst_instruction *inst, char *tokens[], int tokensCount)
data->processOpData.multiplydata.summand = ZERO_REGISTER;
data->processOpData.multiplydata.negProd = strcmp(tokens[0], "mneg") == 0;
}
} else {
// Arithmetic/Logic
data->DPROpType = a64inst_DPR_ARITHMLOGIC;