Add handling of all aliases. Add Shift Utility Function
This commit is contained in:
parent
0815d5b6f6
commit
f3e1c1f150
86
src/parser.c
86
src/parser.c
@ -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;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user