mirror of
https://github.com/capstone-engine/capstone.git
synced 2024-11-23 13:39:46 +00:00
887 lines
38 KiB
Python
Executable File
887 lines
38 KiB
Python
Executable File
#!/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()
|