| #!/usr/bin/python |
| # convert LLVM GenAsmWriter.inc for Capstone disassembler. |
| # by Nguyen Anh Quynh, 2019 |
| |
| import sys |
| |
| if len(sys.argv) == 1: |
| print("Syntax: %s <GenAsmWriter.inc> <Output-GenAsmWriter.inc> <Output-GenRegisterName.inc> <arch>" %sys.argv[0]) |
| sys.exit(1) |
| |
| arch = sys.argv[4] |
| f = open(sys.argv[1]) |
| lines = f.readlines() |
| f.close() |
| |
| f1 = open(sys.argv[2], 'w+') |
| |
| f2 = open(sys.argv[3], 'w+') |
| |
| f1.write("/* Capstone Disassembly Engine, http://www.capstone-engine.org */\n") |
| f1.write("/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2019 */\n") |
| f1.write("\n") |
| |
| f2.write("/* Capstone Disassembly Engine, http://www.capstone-engine.org */\n") |
| f2.write("/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2019 */\n") |
| f2.write("\n") |
| |
| need_endif = False |
| in_getRegisterName = False |
| in_printAliasInstr = False |
| fragment_no = None |
| skip_printing = False |
| |
| skip_line = 0 |
| skip_count = 0 |
| |
| def replace_getOp(line): |
| line2 = line |
| if 'MI->getOperand(0)' in line: |
| line2 = line.replace('MI->getOperand(0)', 'MCInst_getOperand(MI, 0)') |
| elif 'MI->getOperand(1)' in line: |
| line2 = line.replace('MI->getOperand(1)', 'MCInst_getOperand(MI, 1)') |
| elif 'MI->getOperand(2)' in line: |
| line2 = line.replace('MI->getOperand(2)', 'MCInst_getOperand(MI, 2)') |
| elif 'MI->getOperand(3)' in line: |
| line2 = line.replace('MI->getOperand(3)', 'MCInst_getOperand(MI, 3)') |
| elif 'MI->getOperand(4)' in line: |
| line2 = line.replace('MI->getOperand(4)', 'MCInst_getOperand(MI, 4)') |
| elif 'MI->getOperand(5)' in line: |
| line2 = line.replace('MI->getOperand(5)', 'MCInst_getOperand(MI, 5)') |
| elif 'MI->getOperand(6)' in line: |
| line2 = line.replace('MI->getOperand(6)', 'MCInst_getOperand(MI, 6)') |
| elif 'MI->getOperand(7)' in line: |
| line2 = line.replace('MI->getOperand(7)', 'MCInst_getOperand(MI, 7)') |
| elif 'MI->getOperand(8)' in line: |
| line2 = line.replace('MI->getOperand(8)', 'MCInst_getOperand(MI, 8)') |
| return line2 |
| |
| def replace_getReg(line): |
| line2 = line |
| if 'MI->getOperand(0).getReg()' in line: |
| line2 = line.replace('MI->getOperand(0).getReg()', 'MCOperand_getReg(MCInst_getOperand(MI, 0))') |
| elif 'MI->getOperand(1).getReg()' in line: |
| line2 = line.replace('MI->getOperand(1).getReg()', 'MCOperand_getReg(MCInst_getOperand(MI, 1))') |
| elif 'MI->getOperand(2).getReg()' in line: |
| line2 = line.replace('MI->getOperand(2).getReg()', 'MCOperand_getReg(MCInst_getOperand(MI, 2))') |
| elif 'MI->getOperand(3).getReg()' in line: |
| line2 = line.replace('MI->getOperand(3).getReg()', 'MCOperand_getReg(MCInst_getOperand(MI, 3))') |
| elif 'MI->getOperand(4).getReg()' in line: |
| line2 = line.replace('MI->getOperand(4).getReg()', 'MCOperand_getReg(MCInst_getOperand(MI, 4))') |
| elif 'MI->getOperand(5).getReg()' in line: |
| line2 = line.replace('MI->getOperand(5).getReg()', 'MCOperand_getReg(MCInst_getOperand(MI, 5))') |
| elif 'MI->getOperand(6).getReg()' in line: |
| line2 = line.replace('MI->getOperand(6).getReg()', 'MCOperand_getReg(MCInst_getOperand(MI, 6))') |
| elif 'MI->getOperand(7).getReg()' in line: |
| line2 = line.replace('MI->getOperand(7).getReg()', 'MCOperand_getReg(MCInst_getOperand(MI, 7))') |
| elif 'MI->getOperand(8).getReg()' in line: |
| line2 = line.replace('MI->getOperand(8).getReg()', 'MCOperand_getReg(MCInst_getOperand(MI, 8))') |
| return line2 |
| |
| # extract param between text() |
| # MRI.getRegClass(AArch64::GPR32spRegClassID).contains(MI->getOperand(1).getReg())) |
| def extract_paren(line, text): |
| i = line.index(text) |
| return line[line.index('(', i)+1 : line.index(')', i)] |
| |
| |
| # extract text between <> |
| # printSVERegOp<'q'> |
| def extract_brackets(line): |
| if '<' in line: |
| return line[line.index('<')+1 : line.index('>')] |
| else: |
| return '' |
| |
| # delete text between <>, including <> |
| # printSVERegOp<'q'> |
| def del_brackets(line): |
| if '<' in line: |
| return line[:line.index('<')] + line[line.index('>') + 1:] |
| else: |
| return line |
| |
| |
| def print_line(line): |
| line = line.replace('::', '_') |
| line = line.replace('nullptr', 'NULL') |
| if not skip_printing: |
| if in_getRegisterName: |
| f2.write(line + "\n") |
| else: |
| f1.write(line + "\n") |
| |
| |
| for line in lines: |
| line = line.rstrip() |
| #print("@", line) |
| |
| # skip Alias |
| if arch.upper() == 'X86': |
| if 'PRINT_ALIAS_INSTR' in line: |
| # done |
| break |
| |
| if skip_line: |
| skip_count += 1 |
| if skip_count <= skip_line: |
| # skip this line |
| continue |
| else: |
| # skip enough number of lines, reset counters |
| skip_line = 0 |
| skip_count = 0 |
| |
| if "::printInstruction" in line: |
| if arch.upper() in ('AARCH64', 'ARM64'): |
| #print_line("static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI)\n{") |
| print_line("static void printInstruction(MCInst *MI, SStream *O)\n{") |
| else: |
| print_line("static void printInstruction(MCInst *MI, SStream *O)\n{") |
| elif 'LLVM_NO_PROFILE_INSTRUMENT_FUNCTION' in line: |
| continue |
| elif 'AArch64InstPrinter::getMnemonic' in line: |
| print_line("static uint64_t getMnemonic(MCInst *MI, SStream *O, unsigned int opcode) {") |
| elif 'return {AsmStrs+(Bits' in line: |
| tmp = line.split(',') |
| prntStr = tmp[0].split('{')[1] |
| print_line("\tSStream_concat0(O, " + prntStr + ");") |
| print_line("\treturn Bits;") |
| elif 'MnemonicInfo = getMnemonic(' in line: |
| continue |
| elif 'O << MnemonicInfo' in line: |
| continue |
| elif 'uint64_t Bits = MnemonicInfo' in line: |
| print_line("\tuint64_t Bits = getMnemonic(MI, O, opcode);") |
| elif 'const char *AArch64InstPrinter::' in line: |
| continue |
| elif 'getRegisterName(' in line: |
| if 'unsigned AltIdx' in line: |
| print_line("static const char *getRegisterName(unsigned RegNo, unsigned AltIdx)\n{") |
| else: |
| print_line("static const char *getRegisterName(unsigned RegNo)\n{") |
| elif 'getRegisterName' in line: |
| in_getRegisterName = True |
| print_line(line) |
| elif '::printAliasInstr' in line: |
| if arch.upper() in ('AARCH64', 'PPC'): |
| print_line("static char *printAliasInstr(MCInst *MI, SStream *OS, MCRegisterInfo *MRI)\n{") |
| print_line(' #define GETREGCLASS_CONTAIN(_class, _reg) MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, _class), MCOperand_getReg(MCInst_getOperand(MI, _reg)))') |
| else: |
| print_line("static bool printAliasInstr(MCInst *MI, SStream *OS)\n{") |
| print_line(" unsigned int I = 0, OpIdx, PrintMethodIdx;") |
| print_line(" char *tmpString;") |
| in_printAliasInstr = True |
| elif 'STI.getFeatureBits()[' in line: |
| if arch.upper() == 'ARM': |
| line2 = line.replace('STI.getFeatureBits()[', 'ARM_getFeatureBits(MI->csh->mode, ') |
| elif arch.upper() == 'AARCH64': |
| line2 = line.replace('STI.getFeatureBits()[', 'AArch64_getFeatureBits(') |
| line2 = line2.replace(']', ')') |
| print_line(line2) |
| elif 'lookupBTIByEncoding' in line: |
| line = line.replace('AArch64BTIHint::', '') |
| line = line.replace('MCOp.getImm()', 'MCOperand_getImm(MCOp)') |
| print_line(line) |
| elif 'lookupPSBByEncoding' in line: |
| line = line.replace('AArch64PSBHint::', '') |
| line = line.replace('MCOp.getImm()', 'MCOperand_getImm(MCOp)') |
| print_line(line) |
| elif ', STI, ' in line: |
| line2 = line.replace(', STI, ', ', ') |
| |
| if 'printSVELogicalImm<' in line: |
| if 'int16' in line: |
| line2 = line2.replace('printSVELogicalImm', 'printSVELogicalImm16') |
| line2 = line2.replace('<int16_t>', '') |
| elif 'int32' in line: |
| line2 = line2.replace('printSVELogicalImm', 'printSVELogicalImm32') |
| line2 = line2.replace('<int32_t>', '') |
| else: |
| line2 = line2.replace('printSVELogicalImm', 'printSVELogicalImm64') |
| line2 = line2.replace('<int64_t>', '') |
| |
| if 'MI->getOperand(' in line: |
| line2 = replace_getOp(line2) |
| |
| # C++ template |
| if 'printPrefetchOp' in line2: |
| param = extract_brackets(line2) |
| if param == '': |
| param = 'false' |
| line2 = del_brackets(line2) |
| line2 = line2.replace(', O);', ', O, %s);' %param) |
| line2 = line2.replace(', OS);', ', OS, %s);' %param) |
| elif '<false>' in line2: |
| line2 = line2.replace('<false>', '') |
| line2 = line2.replace(', O);', ', O, false);') |
| line2 = line2.replace('STI, ', '') |
| elif '<true>' in line: |
| line2 = line2.replace('<true>', '') |
| line2 = line2.replace(', O);', ', O, true);') |
| line2 = line2.replace('STI, ', '') |
| elif 'printAdrLabelOperand' in line: |
| # C++ template |
| if '<0>' in line: |
| line2 = line2.replace('<0>', '') |
| line2 = line2.replace(', O);', ', O, 0);') |
| elif '<1>' in line: |
| line2 = line2.replace('<1>', '') |
| line2 = line2.replace(', O);', ', O, 1);') |
| elif '<2>' in line: |
| line2 = line2.replace('<2>', '') |
| line2 = line2.replace(', O);', ', O, 2);') |
| elif 'printImm8OptLsl' in line2: |
| param = extract_brackets(line2) |
| line2 = del_brackets(line2) |
| if '8' in param or '16' in param or '32' in param: |
| line2 = line2.replace('printImm8OptLsl', 'printImm8OptLsl32') |
| elif '64' in param: |
| line2 = line2.replace('printImm8OptLsl', 'printImm8OptLsl64') |
| elif 'printLogicalImm' in line2: |
| param = extract_brackets(line2) |
| line2 = del_brackets(line2) |
| if '8' in param or '16' in param or '32' in param: |
| line2 = line2.replace('printLogicalImm', 'printLogicalImm32') |
| elif '64' in param: |
| line2 = line2.replace('printLogicalImm', 'printLogicalImm64') |
| elif 'printSVERegOp' in line2 or 'printGPRSeqPairsClassOperand' in line2 or 'printTypedVectorList' in line2 or 'printPostIncOperand' in line2 or 'printImmScale' in line2 or 'printRegWithShiftExtend' in line2 or 'printUImm12Offset' in line2 or 'printExactFPImm' in line2 or 'printMemExtend' in line2 or 'printZPRasFPR' in line2 or 'printMatrixTileVector' in line2 or 'printMatrix<' in line2 or 'printSImm' in line2: |
| param = extract_brackets(line2) |
| if param == '': |
| param = '0' |
| line2 = del_brackets(line2) |
| line2 = line2.replace(', O);', ', O, %s);' %param) |
| line2 = line2.replace(', OS);', ', OS, %s);' %param) |
| elif 'printComplexRotationOp' in line: |
| # printComplexRotationOp<90, 0>(MI, 5, STI, O); |
| bracket_content = line2[line2.index('<') + 1 : line2.index('>')] |
| line2 = line2.replace('<' + bracket_content + '>', '') |
| line2 = line2.replace(' O);', ' O, %s);' %bracket_content) |
| elif 'printAlignedLabel' in line2 or 'printAdrpLabel' in line2: |
| line2 = line2.replace('Address, ', '') |
| |
| print_line(line2) |
| elif "static const char AsmStrs[]" in line: |
| print_line("#ifndef CAPSTONE_DIET") |
| print_line(" static const char AsmStrs[] = {") |
| need_endif = True |
| elif "static const char AsmStrsNoRegAltName[]" in line: |
| print_line("#ifndef CAPSTONE_DIET") |
| print_line(" static const char AsmStrsNoRegAltName[] = {") |
| need_endif = True |
| elif line == ' O << "\\t";': |
| print_line(" unsigned int opcode = MCInst_getOpcode(MI);") |
| print_line(' // printf("opcode = %u\\n", opcode);'); |
| elif 'MI->getOpcode()' in line: |
| if 'switch' in line: |
| line2 = line.replace('MI->getOpcode()', 'MCInst_getOpcode(MI)') |
| else: |
| line2 = line.replace('MI->getOpcode()', 'opcode') |
| print_line(line2) |
| |
| elif 'O << ' in line: |
| if '"' in line: |
| line2 = line.lower() |
| line2 = line2.replace('o << ', 'SStream_concat0(O, '); |
| else: |
| line2 = line.replace('O << ', 'SStream_concat0(O, '); |
| line2 = line2.replace("'", '"') |
| line2 = line2.replace(';', ');') |
| if '" : "' in line2: # "segment : offset" in X86 |
| line2 = line2.replace('" : "', '":"') |
| |
| # ARM |
| print_line(line2) |
| |
| if '", #0"' in line2: |
| print_line(' op_addImm(MI, 0);') |
| |
| if '", #1"' in line2: |
| print_line(' op_addImm(MI, 1);') |
| |
| # PowerPC |
| if '", 268"' in line2: |
| print_line(' op_addImm(MI, 268);') |
| |
| elif '", 256"' in line2: |
| print_line(' op_addImm(MI, 256);') |
| |
| elif '", 0, "' in line2 or '", 0"' in line2: |
| print_line(' op_addImm(MI, 0);') |
| |
| elif '", -1"' in line2: |
| print_line(' op_addImm(MI, -1);') |
| |
| |
| if '], [' in line2 or ']!, [' in line2: |
| print_line(' set_mem_access(MI, false);') |
| print_line(' set_mem_access(MI, true);') |
| |
| elif "\"[\"" in line2: |
| # Check for SME_Index specific string of only "[" |
| print_line(' set_sme_index(MI, true);') |
| |
| elif '[' in line2: |
| if not '[]' in line2: |
| print_line(' set_mem_access(MI, true);') |
| |
| elif ']' in line2: |
| if not '[]' in line2: |
| print_line(' set_mem_access(MI, false);') |
| |
| if '".f64\\t"' in line2: |
| print_line(' ARM_addVectorDataType(MI, ARM_VECTORDATA_F64);') |
| elif '".f32\\t"' in line2: |
| print_line(' ARM_addVectorDataType(MI, ARM_VECTORDATA_F32);') |
| elif '".f16\\t"' in line2: |
| print_line(' ARM_addVectorDataType(MI, ARM_VECTORDATA_F16);') |
| elif '".s64\\t"' in line2: |
| print_line(' ARM_addVectorDataType(MI, ARM_VECTORDATA_S64);') |
| elif '".s32\\t"' in line2: |
| print_line(' ARM_addVectorDataType(MI, ARM_VECTORDATA_S32);') |
| elif '".s16\\t"' in line2: |
| print_line(' ARM_addVectorDataType(MI, ARM_VECTORDATA_S16);') |
| elif '".s8\\t"' in line2: |
| print_line(' ARM_addVectorDataType(MI, ARM_VECTORDATA_S8);') |
| elif '".u64\\t"' in line2: |
| print_line(' ARM_addVectorDataType(MI, ARM_VECTORDATA_U64);') |
| elif '".u32\\t"' in line2: |
| print_line(' ARM_addVectorDataType(MI, ARM_VECTORDATA_U32);') |
| elif '".u16\\t"' in line2: |
| print_line(' ARM_addVectorDataType(MI, ARM_VECTORDATA_U16);') |
| elif '".u8\\t"' in line2: |
| print_line(' ARM_addVectorDataType(MI, ARM_VECTORDATA_U8);') |
| elif '".i64\\t"' in line2: |
| print_line(' ARM_addVectorDataType(MI, ARM_VECTORDATA_I64);') |
| elif '".i32\\t"' in line2: |
| print_line(' ARM_addVectorDataType(MI, ARM_VECTORDATA_I32);') |
| elif '".i16\\t"' in line2: |
| print_line(' ARM_addVectorDataType(MI, ARM_VECTORDATA_I16);') |
| elif '".i8\\t"' in line2: |
| print_line(' ARM_addVectorDataType(MI, ARM_VECTORDATA_I8);') |
| elif '".f16.f64\\t"' in line2: |
| print_line(' ARM_addVectorDataType(MI, ARM_VECTORDATA_F16F64);') |
| elif '".f64.f16\\t"' in line2: |
| print_line(' ARM_addVectorDataType(MI, ARM_VECTORDATA_F64F16);') |
| elif '".f16.f32\\t"' in line2: |
| print_line(' ARM_addVectorDataType(MI, ARM_VECTORDATA_F16F32);') |
| elif '".f32.f16\\t"' in line2: |
| print_line(' ARM_addVectorDataType(MI, ARM_VECTORDATA_F32F16);') |
| elif '".f64.f32\\t"' in line2: |
| print_line(' ARM_addVectorDataType(MI, ARM_VECTORDATA_F64F32);') |
| elif '".f32.f64\\t"' in line2: |
| print_line(' ARM_addVectorDataType(MI, ARM_VECTORDATA_F32F64);') |
| elif '".s32.f32\\t"' in line2: |
| print_line(' ARM_addVectorDataType(MI, ARM_VECTORDATA_S32F32);') |
| elif '".f32.s32\\t"' in line2: |
| print_line(' ARM_addVectorDataType(MI, ARM_VECTORDATA_F32S32);') |
| elif '".u32.f32\\t"' in line2: |
| print_line(' ARM_addVectorDataType(MI, ARM_VECTORDATA_U32F32);') |
| elif '".f32.u32\\t"' in line2: |
| print_line(' ARM_addVectorDataType(MI, ARM_VECTORDATA_F32U32);') |
| elif '".p8\\t"' in line2: |
| print_line(' ARM_addVectorDataType(MI, ARM_VECTORDATA_P8);') |
| elif '".f64.s16\\t"' in line2: |
| print_line(' ARM_addVectorDataType(MI, ARM_VECTORDATA_F64S16);') |
| elif '".s16.f64\\t"' in line2: |
| print_line(' ARM_addVectorDataType(MI, ARM_VECTORDATA_S16F64);') |
| elif '".f32.s16\\t"' in line2: |
| print_line(' ARM_addVectorDataType(MI, ARM_VECTORDATA_F32S16);') |
| elif '".s16.f32\\t"' in line2: |
| print_line(' ARM_addVectorDataType(MI, ARM_VECTORDATA_S16F32);') |
| elif '".f64.s32\\t"' in line2: |
| print_line(' ARM_addVectorDataType(MI, ARM_VECTORDATA_F64S32);') |
| elif '".s32.f64\\t"' in line2: |
| print_line(' ARM_addVectorDataType(MI, ARM_VECTORDATA_S32F64);') |
| elif '".f64.u16\\t"' in line2: |
| print_line(' ARM_addVectorDataType(MI, ARM_VECTORDATA_F64U16);') |
| elif '".u16.f64\\t"' in line2: |
| print_line(' ARM_addVectorDataType(MI, ARM_VECTORDATA_U16F64);') |
| elif '".f32.u16\\t"' in line2: |
| print_line(' ARM_addVectorDataType(MI, ARM_VECTORDATA_F32U16);') |
| elif '".u16.f32\\t"' in line2: |
| print_line(' ARM_addVectorDataType(MI, ARM_VECTORDATA_U16F32);') |
| elif '".f64.u32\\t"' in line2: |
| print_line(' ARM_addVectorDataType(MI, ARM_VECTORDATA_F64U32);') |
| elif '".u32.f64\\t"' in line2: |
| print_line(' ARM_addVectorDataType(MI, ARM_VECTORDATA_U32F64);') |
| elif '".f16.u32\\t"' in line2: |
| print_line(' ARM_addVectorDataType(MI, ARM_VECTORDATA_F16U32);') |
| elif '".u32.f16\\t"' in line2: |
| print_line(' ARM_addVectorDataType(MI, ARM_VECTORDATA_U32F16);') |
| elif '".f16.u16\\t"' in line2: |
| print_line(' ARM_addVectorDataType(MI, ARM_VECTORDATA_F16U16);') |
| elif '".u16.f16\\t"' in line2: |
| print_line(' ARM_addVectorDataType(MI, ARM_VECTORDATA_U16F16);') |
| elif '"\\tlr"' in line2: |
| print_line(' ARM_addReg(MI, ARM_REG_LR);') |
| elif '"\\tapsr_nzcv, fpscr"' in line2: |
| print_line(' ARM_addReg(MI, ARM_REG_APSR_NZCV);') |
| print_line(' ARM_addReg(MI, ARM_REG_FPSCR);') |
| elif '"\\tpc, lr"' in line2: |
| print_line(' ARM_addReg(MI, ARM_REG_PC);') |
| print_line(' ARM_addReg(MI, ARM_REG_LR);') |
| elif '"\\tfpscr, "' in line2: |
| print_line(' ARM_addReg(MI, ARM_REG_FPSCR);') |
| elif '"\\tfpexc, "' in line2: |
| print_line(' ARM_addReg(MI, ARM_REG_FPEXC);') |
| elif '"\\tfpinst, "' in line2: |
| print_line(' ARM_addReg(MI, ARM_REG_FPINST);') |
| elif '"\\tfpinst2, "' in line2: |
| print_line(' ARM_addReg(MI, ARM_REG_FPINST2);') |
| elif '"\\tfpsid, "' in line2: |
| print_line(' ARM_addReg(MI, ARM_REG_FPSID);') |
| elif '"\\tsp, "' in line2: |
| print_line(' ARM_addReg(MI, ARM_REG_SP);') |
| elif '"\\tsp!, "' in line2: |
| print_line(' ARM_addReg(MI, ARM_REG_SP);') |
| elif '", apsr"' in line2: |
| print_line(' ARM_addReg(MI, ARM_REG_APSR);') |
| elif '", spsr"' in line2: |
| print_line(' ARM_addReg(MI, ARM_REG_SPSR);') |
| elif '", fpscr"' in line2: |
| print_line(' ARM_addReg(MI, ARM_REG_FPSCR);') |
| elif '", fpscr"' in line2: |
| print_line(' ARM_addReg(MI, ARM_REG_FPSCR);') |
| elif '", fpexc"' in line2: |
| print_line(' ARM_addReg(MI, ARM_REG_FPEXC);') |
| elif '", fpinst"' in line2: |
| print_line(' ARM_addReg(MI, ARM_REG_FPINST);') |
| elif '", fpinst2"' in line2: |
| print_line(' ARM_addReg(MI, ARM_REG_FPINST2);') |
| elif '", fpsid"' in line2: |
| print_line(' ARM_addReg(MI, ARM_REG_FPSID);') |
| elif '", mvfr0"' in line2: |
| print_line(' ARM_addReg(MI, ARM_REG_MVFR0);') |
| elif '", mvfr1"' in line2: |
| print_line(' ARM_addReg(MI, ARM_REG_MVFR1);') |
| elif '", mvfr2"' in line2: |
| print_line(' ARM_addReg(MI, ARM_REG_MVFR2);') |
| elif '.8\\t' in line2: |
| print_line(' ARM_addVectorDataSize(MI, 8);') |
| elif '.16\\t' in line2: |
| print_line(' ARM_addVectorDataSize(MI, 16);') |
| elif '.32\\t' in line2: |
| print_line(' ARM_addVectorDataSize(MI, 32);') |
| elif '.64\\t' in line2: |
| print_line(' ARM_addVectorDataSize(MI, 64);') |
| elif '" ^"' in line2: |
| print_line(' ARM_addUserMode(MI);') |
| |
| if '.16b' in line2: |
| print_line(' arm64_op_addVectorArrSpecifier(MI, ARM64_VAS_16B);') |
| elif '.8b' in line2: |
| print_line(' arm64_op_addVectorArrSpecifier(MI, ARM64_VAS_8B);') |
| elif '.4b' in line2: |
| print_line(' arm64_op_addVectorArrSpecifier(MI, ARM64_VAS_4B);') |
| elif '.b' in line2: |
| print_line(' arm64_op_addVectorArrSpecifier(MI, ARM64_VAS_1B);') |
| elif '.8h' in line2: |
| print_line(' arm64_op_addVectorArrSpecifier(MI, ARM64_VAS_8H);') |
| elif '.4h' in line2: |
| print_line(' arm64_op_addVectorArrSpecifier(MI, ARM64_VAS_4H);') |
| elif '.2h' in line2: |
| print_line(' arm64_op_addVectorArrSpecifier(MI, ARM64_VAS_2H);') |
| elif '.h' in line2: |
| print_line(' arm64_op_addVectorArrSpecifier(MI, ARM64_VAS_1H);') |
| elif '.4s' in line2: |
| print_line(' arm64_op_addVectorArrSpecifier(MI, ARM64_VAS_4S);') |
| elif '.2s' in line2: |
| print_line(' arm64_op_addVectorArrSpecifier(MI, ARM64_VAS_2S);') |
| elif '.s' in line2: |
| print_line(' arm64_op_addVectorArrSpecifier(MI, ARM64_VAS_1S);') |
| elif '.2d' in line2: |
| print_line(' arm64_op_addVectorArrSpecifier(MI, ARM64_VAS_2D);') |
| elif '.1d' in line2: |
| print_line(' arm64_op_addVectorArrSpecifier(MI, ARM64_VAS_1D);') |
| elif '.1q' in line2: |
| print_line(' arm64_op_addVectorArrSpecifier(MI, ARM64_VAS_1Q);') |
| |
| if '#0.0' in line2: |
| print_line(' arm64_op_addFP(MI, 0);') |
| elif '#0' in line2: |
| print_line(' arm64_op_addImm(MI, 0);') |
| elif '#8' in line2: |
| print_line(' arm64_op_addImm(MI, 8);') |
| elif '#16' in line2: |
| print_line(' arm64_op_addImm(MI, 16);') |
| elif '#32' in line2: |
| print_line(' arm64_op_addImm(MI, 32);') |
| |
| # X86 |
| if '", %rax"' in line2 or '", rax"' in line2: |
| print_line(' op_addReg(MI, X86_REG_RAX);') |
| elif '", %eax"' in line2 or '", eax"' in line2: |
| print_line(' op_addReg(MI, X86_REG_EAX);') |
| elif '", %ax"' in line2 or '", ax"' in line2: |
| print_line(' op_addReg(MI, X86_REG_AX);') |
| elif '", %al"' in line2 or '", al"' in line2: |
| print_line(' op_addReg(MI, X86_REG_AL);') |
| elif '", %dx"' in line2 or '", dx"' in line2: |
| print_line(' op_addReg(MI, X86_REG_DX);') |
| elif '", %st(0)"' in line2 or '", st(0)"' in line2: |
| print_line(' op_addReg(MI, X86_REG_ST0);') |
| elif '", 1"' in line2: |
| print_line(' op_addImm(MI, 1);') |
| elif '", cl"' in line2: |
| print_line(' op_addReg(MI, X86_REG_CL);') |
| elif '"{1to2}, "' in line2: |
| print_line(' op_addAvxBroadcast(MI, X86_AVX_BCAST_2);') |
| elif '"{1to4}, "' in line2: |
| print_line(' op_addAvxBroadcast(MI, X86_AVX_BCAST_4);') |
| elif '"{1to8}, "' in line2: |
| print_line(' op_addAvxBroadcast(MI, X86_AVX_BCAST_8);') |
| elif '"{1to16}, "' in line2: |
| print_line(' op_addAvxBroadcast(MI, X86_AVX_BCAST_16);') |
| elif '{z}{sae}' in line2: |
| print_line(' op_addAvxSae(MI);') |
| print_line(' op_addAvxZeroOpmask(MI);') |
| elif ('{z}' in line2): |
| print_line(' op_addAvxZeroOpmask(MI);') |
| elif '{sae}' in line2: |
| print_line(' op_addAvxSae(MI);') |
| elif 'llvm_unreachable("Invalid command number.");' in line: |
| line2 = line.replace('llvm_unreachable("Invalid command number.");', '// unreachable') |
| print_line(line2) |
| elif ('assert(' in line) or ('assert (' in line): |
| pass |
| elif 'Invalid alt name index' in line: |
| pass |
| elif '::' in line and 'case ' in line: |
| #print_line(line2) |
| print_line(line) |
| elif 'MI->getNumOperands()' in line: |
| line2 = line.replace('MI->getNumOperands()', 'MCInst_getNumOperands(MI)') |
| print_line(line2) |
| elif 'const MCOperand &MCOp' in line: |
| line2 = line.replace('const MCOperand &MCOp', 'MCOperand *MCOp') |
| print_line(line2) |
| elif 'MI->getOperand(0).isImm()' in line: |
| line2 = line.replace('MI->getOperand(0).isImm()', 'MCOperand_isImm(MCInst_getOperand(MI, 0))') |
| print_line(line2) |
| elif 'MI->getOperand(1).isImm()' in line: |
| line2 = line.replace('MI->getOperand(1).isImm()', 'MCOperand_isImm(MCInst_getOperand(MI, 1))') |
| print_line(line2) |
| elif 'MI->getOperand(2).isImm()' in line: |
| line2 = line.replace('MI->getOperand(2).isImm()', 'MCOperand_isImm(MCInst_getOperand(MI, 2))') |
| print_line(line2) |
| elif 'MI->getOperand(3).isImm()' in line: |
| line2 = line.replace('MI->getOperand(3).isImm()', 'MCOperand_isImm(MCInst_getOperand(MI, 3))') |
| print_line(line2) |
| elif 'MI->getOperand(4).isImm()' in line: |
| line2 = line.replace('MI->getOperand(4).isImm()', 'MCOperand_isImm(MCInst_getOperand(MI, 4))') |
| print_line(line2) |
| elif 'MI->getOperand(5).isImm()' in line: |
| line2 = line.replace('MI->getOperand(5).isImm()', 'MCOperand_isImm(MCInst_getOperand(MI, 5))') |
| print_line(line2) |
| elif 'MI->getOperand(6).isImm()' in line: |
| line2 = line.replace('MI->getOperand(6).isImm()', 'MCOperand_isImm(MCInst_getOperand(MI, 6))') |
| print_line(line2) |
| elif 'MI->getOperand(7).isImm()' in line: |
| line2 = line.replace('MI->getOperand(7).isImm()', 'MCOperand_isImm(MCInst_getOperand(MI, 7))') |
| print_line(line2) |
| elif 'MI->getOperand(8).isImm()' in line: |
| line2 = line.replace('MI->getOperand(8).isImm()', 'MCOperand_isImm(MCInst_getOperand(MI, 8))') |
| print_line(line2) |
| elif 'MI->getOperand(0).getImm()' in line: |
| line2 = line.replace('MI->getOperand(0).getImm()', 'MCOperand_getImm(MCInst_getOperand(MI, 0))') |
| print_line(line2) |
| elif 'MI->getOperand(1).getImm()' in line: |
| line2 = line.replace('MI->getOperand(1).getImm()', 'MCOperand_getImm(MCInst_getOperand(MI, 1))') |
| print_line(line2) |
| elif 'MI->getOperand(2).getImm()' in line: |
| line2 = line.replace('MI->getOperand(2).getImm()', 'MCOperand_getImm(MCInst_getOperand(MI, 2))') |
| print_line(line2) |
| elif 'MI->getOperand(3).getImm()' in line: |
| line2 = line.replace('MI->getOperand(3).getImm()', 'MCOperand_getImm(MCInst_getOperand(MI, 3))') |
| print_line(line2) |
| elif 'MI->getOperand(4).getImm()' in line: |
| line2 = line.replace('MI->getOperand(4).getImm()', 'MCOperand_getImm(MCInst_getOperand(MI, 4))') |
| print_line(line2) |
| elif 'MI->getOperand(5).getImm()' in line: |
| line2 = line.replace('MI->getOperand(5).getImm()', 'MCOperand_getImm(MCInst_getOperand(MI, 5))') |
| print_line(line2) |
| elif 'MI->getOperand(6).getImm()' in line: |
| line2 = line.replace('MI->getOperand(6).getImm()', 'MCOperand_getImm(MCInst_getOperand(MI, 6))') |
| print_line(line2) |
| elif 'MI->getOperand(7).getImm()' in line: |
| line2 = line.replace('MI->getOperand(7).getImm()', 'MCOperand_getImm(MCInst_getOperand(MI, 7))') |
| print_line(line2) |
| elif 'MI->getOperand(8).getImm()' in line: |
| line2 = line.replace('MI->getOperand(8).getImm()', 'MCOperand_getImm(MCInst_getOperand(MI, 8))') |
| print_line(line2) |
| elif 'MRI.getRegClass(' in line: |
| classid = extract_paren(line, 'getRegClass(') |
| operand = extract_paren(line, 'getOperand') |
| line2 = line.replace('MI->getNumOperands()', 'MCInst_getNumOperands(MI)') |
| line2 = ' GETREGCLASS_CONTAIN(%s, %s)' %(classid, operand) |
| if line.endswith('())) {'): |
| line2 += ') {' |
| elif line.endswith(' {'): |
| line2 += ' {' |
| elif line.endswith(' &&'): |
| line2 += ' &&' |
| print_line(line2) |
| elif 'MI->getOperand(' in line and 'isReg' in line: |
| operand = extract_paren(line, 'getOperand') |
| line2 = ' MCOperand_isReg(MCInst_getOperand(MI, %s))' %(operand) |
| # MI->getOperand(1).isReg() && |
| if line.endswith(' {'): |
| line2 += ' {' |
| elif line.endswith(' &&'): |
| line2 += ' &&' |
| print_line(line2) |
| elif 'MI->getOperand(' in line and 'getReg' in line: |
| line2 = replace_getReg(line) |
| # one more time |
| line2 = replace_getReg(line2) |
| print_line(line2) |
| elif ' return false;' in line and in_printAliasInstr: |
| print_line(' return NULL;') |
| elif 'MCOp.isImm()' in line: |
| line2 = line.replace('MCOp.isImm()', 'MCOperand_isImm(MCOp)') |
| print_line(line2) |
| elif 'MCOp.getImm()' in line: |
| line2 = line.replace('MCOp.getImm()', 'MCOperand_getImm(MCOp)') |
| if 'int64_t Val =' in line: |
| line2 = line2.replace('int64_t Val =', 'Val =') |
| print_line(line2) |
| elif 'isSVEMaskOfIdenticalElements<' in line: |
| if 'int8' in line: |
| line2 = line.replace('isSVEMaskOfIdenticalElements', 'isSVEMaskOfIdenticalElements8') |
| line2 = line2.replace('<int8_t>', '') |
| elif 'int16' in line: |
| line2 = line.replace('isSVEMaskOfIdenticalElements', 'isSVEMaskOfIdenticalElements16') |
| line2 = line2.replace('<int16_t>', '') |
| elif 'int32' in line: |
| line2 = line.replace('isSVEMaskOfIdenticalElements', 'isSVEMaskOfIdenticalElements32') |
| line2 = line2.replace('<int32_t>', '') |
| else: |
| line2 = line.replace('isSVEMaskOfIdenticalElements', 'isSVEMaskOfIdenticalElements64') |
| line2 = line2.replace('<int64_t>', '') |
| print_line(line2) |
| elif 'switch (PredicateIndex) {' in line: |
| print_line(' int64_t Val;') |
| print_line(line) |
| elif 'uint32_t(' in line and in_printAliasInstr: |
| line = line.replace('uint32_t(', '') |
| line = line.replace(')', '') |
| print_line(line) |
| elif '#ifndef NDEBUG' in line and in_printAliasInstr: |
| print_line(""" |
| char *AsmString; |
| const size_t OpToSize = sizeof(OpToPatterns) / sizeof(PatternsForOpcode); |
| |
| const unsigned opcode = MCInst_getOpcode(MI); |
| |
| // Check for alias |
| int OpToIndex = 0; |
| for(int i = 0; i < OpToSize; i++){ |
| if(OpToPatterns[i].Opcode == opcode){ |
| OpToIndex = i; |
| break; |
| } |
| } |
| // Check for match |
| if(opcode != OpToPatterns[OpToIndex].Opcode) |
| return NULL; |
| |
| const PatternsForOpcode opToPat = OpToPatterns[OpToIndex]; |
| |
| // Try all patterns for this opcode |
| uint32_t AsmStrOffset = ~0U; |
| int patIdx = opToPat.PatternStart; |
| while(patIdx < (opToPat.PatternStart + opToPat.NumPatterns)){ |
| // Check operand count first |
| if(MCInst_getNumOperands(MI) != Patterns[patIdx].NumOperands) |
| return NULL; |
| |
| // Test all conditions for this pattern |
| int condIdx = Patterns[patIdx].AliasCondStart; |
| int opIdx = 0; |
| bool allPass = true; |
| while(condIdx < (Patterns[patIdx].AliasCondStart + Patterns[patIdx].NumConds)){ |
| MCOperand *opnd = MCInst_getOperand(MI, opIdx); |
| opIdx++; |
| // Not concerned with any Feature related conditions as STI is disregarded |
| switch (Conds[condIdx].Kind) |
| { |
| case AliasPatternCond_K_Ignore : |
| // Operand can be anything. |
| break; |
| case AliasPatternCond_K_Reg : |
| // Operand must be a specific register. |
| allPass = allPass && (MCOperand_isReg(opnd) && MCOperand_getReg(opnd) == Conds[condIdx].Value); |
| break; |
| case AliasPatternCond_K_TiedReg : |
| // Operand must match the register of another operand. |
| allPass = allPass && (MCOperand_isReg(opnd) && MCOperand_getReg(opnd) == |
| MCOperand_getReg(MCInst_getOperand(MI, Conds[condIdx].Value))); |
| break; |
| case AliasPatternCond_K_Imm : |
| // Operand must be a specific immediate. |
| allPass = allPass && (MCOperand_isImm(opnd) && MCOperand_getImm(opnd) == Conds[condIdx].Value); |
| break; |
| case AliasPatternCond_K_RegClass : |
| // Operand must be a register in this class. Value is a register class id. |
| allPass = allPass && (MCOperand_isReg(opnd) && GETREGCLASS_CONTAIN(Conds[condIdx].Value, (opIdx-1))); |
| break; |
| case AliasPatternCond_K_Custom : |
| // Operand must match some custom criteria. |
| allPass = allPass && AArch64InstPrinterValidateMCOperand(opnd, Conds[condIdx].Value); |
| break; |
| case AliasPatternCond_K_Feature : |
| case AliasPatternCond_K_NegFeature : |
| case AliasPatternCond_K_OrFeature : |
| case AliasPatternCond_K_OrNegFeature : |
| case AliasPatternCond_K_EndOrFeatures : |
| default : |
| break; |
| } |
| condIdx++; |
| } |
| if(allPass){ |
| AsmStrOffset = Patterns[patIdx].AsmStrOffset; |
| break; |
| } |
| patIdx++; |
| } |
| |
| // If no alias matched, don't print an alias. |
| if (AsmStrOffset == ~0U) |
| return NULL; |
| |
| AsmString = cs_strdup(&AsmStrings[AsmStrOffset]); |
| |
| tmpString = cs_strdup(AsmString); |
| |
| while (AsmString[I] != ' ' && AsmString[I] != '\\t' && |
| AsmString[I] != '$' && AsmString[I] != '\\0') |
| ++I; |
| |
| tmpString[I] = 0; |
| SStream_concat0(OS, tmpString); |
| |
| if (AsmString[I] != '\\0') { |
| if (AsmString[I] == ' ' || AsmString[I] == '\\t') { |
| SStream_concat0(OS, " "); |
| ++I; |
| } |
| |
| bool isSME = false; |
| do { |
| if (AsmString[I] == '$') { |
| ++I; |
| if (AsmString[I] == (char)0xff) { |
| ++I; |
| OpIdx = AsmString[I++] - 1; |
| PrintMethodIdx = AsmString[I++] - 1; |
| printCustomAliasOperand(MI, 0, OpIdx, PrintMethodIdx, OS); |
| } else |
| printOperand(MI, (unsigned)(AsmString[I++]) - 1, OS); |
| } else { |
| if (AsmString[I] == '[') { |
| if (AsmString[I-1] != ' ') { |
| set_sme_index(MI, true); |
| isSME = true; |
| } else { |
| set_mem_access(MI, true); |
| } |
| } else if (AsmString[I] == ']') { |
| if (isSME) { |
| set_sme_index(MI, false); |
| isSME = false; |
| } else { |
| set_mem_access(MI, false); |
| } |
| } |
| SStream_concat1(OS, AsmString[I++]); |
| } |
| } while (AsmString[I] != '\\0'); |
| } |
| cs_mem_free(AsmString); |
| return tmpString; |
| } |
| """) |
| in_printAliasInstr = False |
| # skip next few lines |
| skip_printing = True |
| elif '::printCustomAliasOperand' in line: |
| # print again |
| skip_printing = False |
| print_line('static void printCustomAliasOperand(') |
| elif 'const MCSubtargetInfo &STI' in line: |
| pass |
| elif 'const MCInst *MI' in line: |
| line2 = line.replace('const MCInst *MI', 'MCInst *MI') |
| print_line(line2) |
| elif 'llvm_unreachable("' in line: |
| if 'default: ' in line: |
| print_line(' default:') |
| elif 'llvm_unreachable("Unknown MCOperandPredicate kind")' in line: |
| print_line(' return false; // never reach') |
| else: |
| pass |
| elif 'raw_ostream &' in line: |
| line2 = line.replace('raw_ostream &', 'SStream *') |
| if line2.endswith(' {'): |
| line2 = line2.replace(' {', '\n{') |
| print_line(line2) |
| elif 'printPredicateOperand(' in line and 'STI, ' in line: |
| line2 = line.replace('STI, ', '') |
| print_line(line2) |
| elif '// Fragment ' in line: |
| # // Fragment 0 encoded into 6 bits for 51 unique commands. |
| tmp = line.strip().split(' ') |
| fragment_no = tmp[2] |
| print_line(line) |
| elif ('switch ((' in line or 'if ((' in line) and 'Bits' in line: |
| # switch ((Bits >> 14) & 63) { |
| bits = line.strip() |
| bits = bits.replace('switch ', '') |
| bits = bits.replace('if ', '') |
| bits = bits.replace('{', '') |
| bits = bits.strip() |
| print_line(' // printf("Fragment %s: %%"PRIu64"\\n", %s);' %(fragment_no, bits)) |
| print_line(line) |
| elif not skip_printing: |
| print_line(line) |
| |
| if line == ' };': |
| if need_endif and not in_getRegisterName: |
| # endif only for AsmStrs when we are not inside getRegisterName() |
| print_line("#endif") |
| need_endif = False |
| elif 'return AsmStrs+RegAsmOffset[RegNo-1];' in line: |
| if in_getRegisterName: |
| # return NULL for register name on Diet mode |
| print_line("#else") |
| print_line(" return NULL;") |
| print_line("#endif") |
| print_line("}") |
| need_endif = False |
| in_getRegisterName = False |
| # skip 1 line |
| skip_line = 1 |
| elif line == ' }': |
| # ARM64 |
| if in_getRegisterName: |
| # return NULL for register name on Diet mode |
| print_line("#else") |
| print_line(" return NULL;") |
| print_line("#endif") |
| print_line("}") |
| need_endif = False |
| in_getRegisterName = False |
| # skip 1 line |
| skip_line = 1 |
| elif 'default:' in line: |
| # ARM64 |
| if in_getRegisterName: |
| # get the size of RegAsmOffsetvreg[] |
| print_line(" return (const char *)(sizeof(RegAsmOffsetvreg)/sizeof(RegAsmOffsetvreg[0]));") |
| |
| |
| f1.close() |
| f2.close() |