#!/usr/bin/env python # see the Makefile for how to invoke me import os import re import sys import string import binascii sys.path.append('./arm_pcode_parser') import codegencpp # globals g_code = '' g_lineNum = 0 g_lines = [] g_indentLevel = 0 g_DEBUG_GEN = 0 g_DEBUG_DECOMP = 0 header = ''' #include #include #include #include #include "spec.h" /* FIELD_imm8, FIELD_MAX, etc. */ #include "disassembler.h" /* decomp_request, decomp_result */ #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-variable" #pragma clang diagnostic ignored "-Wunused-parameter" #pragma clang diagnostic ignored "-Wunused-function" #pragma clang diagnostic ignored "-Wparentheses-equality" #elif defined(__GNUC__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-variable" #pragma GCC diagnostic ignored "-Wunused-parameter" #pragma GCC diagnostic ignored "-Wunused-function" #pragma GCC diagnostic ignored "-Wparentheses-equality" #endif ''' support = ''' // see A8.4.3 int DecodeImmShift_shift_t(uint8_t enc_bits, uint8_t imm5) { if(enc_bits == 0) return SRType_LSL; else if(enc_bits == 1) return SRType_LSR; else if(enc_bits == 2) return SRType_ASR; else if(enc_bits == 3) { if(imm5 == 0) return SRType_RRX; else return SRType_ROR; } return SRType_ERROR; } int DecodeImmShift_shift_n(uint8_t enc_bits, uint8_t imm5) { if(enc_bits == 0) return imm5; else if(enc_bits == 1) return imm5 ? imm5 : 32; else if(enc_bits == 2) return imm5 ? imm5 : 32; else if(enc_bits == 3) { if(imm5 == 0) return 1; else return imm5; } return -1; } int BadReg(uint8_t reg) { return (reg==13) || (reg==15); } uint64_t Replicate(uint32_t rep, uint32_t before, char before_char, uint32_t after, char after_char, uint8_t times) { uint64_t imm64 = 0; uint32_t i, time; for (time = 0; time < times; time++) { if (time > 0) { for (i = 0; i < before+8; i++) { imm64 <<= 1; imm64 |= before_char; } } imm64 |= rep; for (i = 0; i < after; i++) { imm64 <<= 1; imm64 |= after_char; } } return imm64; } uint32_t VFPExpandImm(uint32_t imm, uint32_t N, uint32_t lowbits) { uint32_t E = 0; if (N == 32) { E = 8; } else { E = 11; } uint32_t F = (N - E) - 1; uint32_t sign = (imm >> 7) & 1; uint32_t exp = ((imm >> 6) & 1) ^ 1; for (uint32_t i = 0; i < E-3; i++) { exp <<= 1; exp |= (imm >> 6) & 1; } exp <<= 2; exp |= (imm >> 4) & 3; uint32_t frac = (imm & 15); frac <<= F-4; uint32_t out = (sign << 31) | (exp << 23) | (frac); return out; } uint32_t AdvSIMDExpandImm(uint32_t op, uint32_t cmode, uint32_t imm8, uint32_t lowbits) { uint32_t testimm8; uint64_t imm64 = 0; uint32_t imm32 = 0; uint32_t i = 0; imm8 = imm8 & 0xff; switch(cmode >> 1) { case 0: testimm8 = 0; imm64 = Replicate(imm8, 24, 0, 0, 0, 2); if (lowbits) return imm64 & 0xffffffff; return 0; break; case 1: testimm8 = 1; imm64 = Replicate(imm8, 16, 0, 8, 0, 2); if (lowbits) return imm64 & 0xffffffff; return 0; break; case 2: testimm8 = 1; imm64 = Replicate(imm8, 8, 0, 16, 0, 2); if (lowbits) return imm64 & 0xffffffff; return 0; break; case 3: testimm8 = 1; imm64 = Replicate(imm8, 0, 0, 24, 0, 2); if (lowbits) return imm64 & 0xffffffff; return 0; break; case 4: testimm8 = 0; imm64 = Replicate(imm8, 8, 0, 0, 0, 4); if (lowbits) return imm64 & 0xff; return 0; break; case 5: testimm8 = 1; imm64 = Replicate(imm8, 0, 0, 8, 0, 4); if (lowbits) return imm64 & 0xffff; return 0; break; case 6: testimm8 = 1; if ((cmode & 1) == 0) { imm64 = Replicate(imm8, 16, 0, 8, 1, 2); } else { imm64 = Replicate(imm8, 8, 0, 16, 1, 2); } if (lowbits) return imm64 & 0xffffffff; return 0; break; case 7: testimm8 = 0; if ((cmode & 1) == 0 && (op & 1) == 0) { imm64 = Replicate(imm8, 0, 0, 0, 0, 8); if (lowbits) return imm8; return 0; } else if ((cmode & 1) == 0 && (op & 1) == 1) { int i, j; for (i = 0; i < 8; i++) { for (j = 0; j < 8; j++) { imm64 |= ((imm8 >> (7-i)) & 1); if (i != 7 || j != 7) imm64 <<= 1; } } } else if ((cmode & 1) == 1 && (op & 1) == 0) { imm32 = ((imm8 >> 7) & 1); imm32 <<= 1; imm32 |= ((imm8 >> 6) & 1) ? 0 : 1; for (i = 0; i < 5; i++) { imm32 <<= 1; imm32 |= (imm8 >> 6) & 1; } imm32 <<= 6; imm32 |= (imm8 & 63); imm32 <<= 19; imm64 = imm32; } else if ((cmode & 1) == 1 && (op & 1) == 1) { //return undefined() } break; } if (testimm8 && imm8 == 0) { //return undefined() } if (lowbits) return imm64 & 0xffffffff; return imm64 >> 32; } uint32_t ROR_C(uint32_t input, int shamt) { shamt %= 32; uint32_t left = input << (32-shamt); uint32_t right = input >> shamt; return left | right; } uint32_t ROR_C_cout(uint32_t input, int shamt) { return ROR_C(input, shamt) >> 31; } int ThumbExpandImm_C_imm32(uint32_t imm12, uint32_t carry_in) { (void)carry_in; if(0 == (imm12 & 0xC00)) { uint32_t idx = (imm12 & 0x300)>>8; uint32_t tmp = imm12 & 0xFF; if(idx==0) { return tmp; } else if(idx==1) { return (tmp << 16) | tmp; } else if(idx==2) { return (tmp << 24) | (tmp << 8); } else { return (tmp << 24) | (tmp << 16) | (tmp << 8) | tmp; } } else { uint32_t value = 0x80 | (imm12 & 0x7F); uint32_t rotamt = (imm12 & 0xF80) >> 7; return ROR_C(value, rotamt); } } int ThumbExpandImm_C_cout(uint32_t imm12, uint32_t carry_in) { if(0 == (imm12 & 0xC00)) { return carry_in; } else { uint32_t unrot_value = 0x80 | (imm12 & 0x7F); return ROR_C_cout(unrot_value, (imm12 & 0xF80) >> 7); } } // TODO: replace with optimized implementation int BitCount(int x) { int answer = 0; while(x) { if(x&1) answer += 1; x>>=1; } return answer; } uint32_t SignExtend(uint32_t val, int inWidth) { int doExtend = val & (1 << (inWidth-1)); if(doExtend) { uint32_t mask = (uint32_t)-1 ^ ((1< bit_width) ? str_width - bit_width : 0; for(int i=0; i 32) bit_width = 32; for(int i=bit_width-1; i>=0; --i) printf("%c", (val & (1<>27'] # ['i', 1, '(instr & 0x04000000)>>26'], # ['', 1, '(instr & 0x2000000)>>25'] # ['', 1, '(instr & 0x100000)>>20'] # ['Rn', 4, '(instr & 0x70000)>>16'], # ['', 1, '(instr & 0x8000)>>15'] # ['imm3', 3, '(instr & 0x7000)>>12'], # ['Rd', 4, '(instr & 0xF00)>>8'], # ['imm8', 8, '(instr & 0xFF)'] def genExtractGeneral(self, varName='instr'): result = [] leftMarg = 0 seen = {} for field in self.text.split(','): # pattern fields -> [varName, #bits] # eg: 'imm3.3' -> ['imm3', 3] varName = '' nBits = 0 if re.match(r'^[01x]+$', field): (varName, nBits) = ('', len(field)) else: # named variables m = re.match(r'^([\w]+)\.(\d+)$', field) if m: (varName, nBits) = (m.group(1), int(m.group(2))) # In a few cases, the encoding diagram contains more than one bit or field with same name. In these cases, the values of all of those bits or fields must be identical. The encoding-specific pseudocode contains a special case using the Consistent() function to specify what happens if they are not identical. Consistent() returns TRUE if all instruction bits or fields with the same name as its argument have the same value, and FALSE otherwise. if varName in seen: varName = varName + "_check" seen[varName] = 1 else: m = re.match(r'^[\(\)01]+$', field) if m: nBits = len(field)//3 else: parseError('genExtractGeneral(): unknown bit extract field %s' % field) # generate the extraction code (mask, shift) shiftAmt = self.width - (leftMarg + nBits) if shiftAmt < 0: parseError('negative shift amount') extract = 'instr & 0x%X' % ((2**nBits - 1) << shiftAmt) if shiftAmt: extract = '(%s)>>%d' % (extract, shiftAmt) # append the result result.append([varName, nBits, extract, field]) # next leftMarg += nBits return result def genExtractToNewVars(self, mgr, varName='instr'): for (varName, length, bitAction, field) in self.genExtractGeneral(): if not varName: continue mgr.add("uint%d_t %s = %s;" % (self.width, varName, bitAction)) def genExtractToElemAssigns(self, varName='instr'): result = '' for (varName, length, bitAction, field) in self.genExtractGeneral(): if not varName: continue fieldName = 'FIELD_' + varName result += "res->fields[%s] = %s;\n" % (fieldName, bitAction) result += "res->fields_mask[%s >> 6] |= 1LL << (%s & 63);\n" % (fieldName, fieldName) result += "char %s_width = %s;\n" % (varName, length) return result # generate a pretty diagram of the bit disection def genExtractToDrawing(self, varName='instr'): extractions = self.genExtractGeneral() # pad field names to length of printed bits, if needed fields = [] for [fieldName, bitLen, code, fieldText] in extractions: if len(fieldText) < bitLen: fieldText = ' '*(bitLen - len(fieldText)) + fieldText fields.append(fieldText) dashes = map(lambda x: '-'*len(x), fields) # eg: printBits((instr & 0xF800)>>11, 5, 5); values = map(lambda x: 'printBits(%s, %d, %d); printf("|");' % \ (x[2], x[1], len(x[3])), extractions) dashLine = 'printf("+%s+\\n");' % '+'.join(dashes) result = [] result.append(dashLine) result.append('printf("|' + '|'.join(fields) + '|\\n");') result.append(dashLine) result.append('printf("|");') result += values result.append('printf("\\n");') result.append(dashLine) return result # get the width of a variable from within the pattern def getVarWidth(self, varName): regex = varName + r'\.(\\d)' #print("trying to get var: %s" % varName) #print("using regex: %s" % regex) m = re.search(regex, self.text) if not m: parseError('variable %s not found in pattern %s using regex %s' % \ (varName, self.text, regex)) return int(m.group(1)) # pretty string representation def __str__(self): result = 'pattern="%s" width=%d stringency=%d' % \ (self.text, self.width, self.stringency) return result #------------------------------------------------------------------------------ # code generation helpers #------------------------------------------------------------------------------ def genEncodingBlock(mgr, encName, arches, fmts, pattern, pcode): #print("genEncodingBlock on %s with pattern: %s" % (encName, pattern)) #status() if not encName: parseError("can't generate encoding block without encoding name!") if not arches: parseError("can't generate encoding block without architecture!") if not fmts: parseError("can't generate encoding block without format!") if not pattern: parseError("can't generate encoding block without pattern!") if not pcode: parseError("can't generate encoding block without pseudocode!") mgr.add("/* Encoding %s */" % encName) mgr.add("/* %s */" % pattern) mgr.add('{') mgr.tab() if pattern.width == 16: mgr.add('uint16_t instr = req->instr_word16;') elif pattern.width == 32: # arm pipelines fetches 2 bytes "halfword" at a time # that's how it knows whether to stay at a single halfword (16-bit thumb) or fetch another (32-bit thumb) mgr.add('uint32_t instr = req->instr_word32;') else: raise Exception("invalid pattern width: %d\n", pattern.width) check = pattern.genCheckMatch() mgr.add("if(%s) {" % check) mgr.tab() if(g_DEBUG_DECOMP): mgr.add('') mgr.add('if(getenv("DEBUG_DECOMP")) {') mgr.tab() mgr.add('printf("using encoding %s\\n\");' % encName) mgr.add('\n'.join(pattern.genExtractToDrawing()) + '') mgr.untab() mgr.add('}') mgr.add('') # save instruction size mgr.add('res->instrSize = %d;' % pattern.width) # generate unpredictable bits check (like "..,(0)(0)(0)(0),...") check = pattern.genCheckUnpredictable() if not check in ['0','1','!0','!1']: mgr.add('if(%s) {' % check) mgr.tab() mgr.add('res->flags |= FLAG_UNPREDICTABLE;') mgr.untab() mgr.add('}') # generate architecture check checks = [] for arch in arches.split(', '): checks.append('!(req->arch & ARCH_%s)' % arch.replace('*', '')) mgr.add("if(%s) {" % ' && '.join(checks)) mgr.tab() mgr.add('res->status |= STATUS_ARCH_UNSUPPORTED;') mgr.untab() mgr.add('}') # save the named fields within the bits temp = pattern.genExtractToElemAssigns() # if 'c' or 'cond' wasn't in the pattern, mark the condition code as always if not re.search(r'c\.\d+', pattern.text) and \ not re.search(r'cond\.\d+', pattern.text): fieldName = 'FIELD_cond' mgr.add('res->fields[%s] = COND_AL;' % fieldName) mgr.add("res->fields_mask[%s >> 6] |= 1LL << (%s & 63);" % (fieldName, fieldName)) #print("at line " + str(g_lineNum) + " trying to indent: %s" % temp) if temp: mgr.add(temp) # save formats in the result mgr.add("static const instruction_format instr_formats[] = ") mgr.add('{') mgr.tab() for fmt in fmts: if ' ' not in fmt: operation = fmt.lower() operandsStr = "" else: operation = fmt[:fmt.index(' ')].lower() operandsStr = fmt[fmt.index(' ') + 1:].strip() flags = "0" if "." in operation: flags += "|INSTR_FORMAT_FLAG_NEON_TYPE_SIZE" operation = operation.replace(".", "") if "." in operation: flags += "|INSTR_FORMAT_FLAG_CONDITIONAL" flags += "|INSTR_FORMAT_FLAG_NEON_SIZE" operation = operation.replace(".", "") if "" in operation: flags += "|INSTR_FORMAT_FLAG_NEON_SINGLE_SIZE" operation = operation.replace("", "") if ".
" in operation: flags += "|INSTR_FORMAT_FLAG_CONDITIONAL" flags += "|INSTR_FORMAT_FLAG_VFP_DATA_SIZE" operation = operation.replace(".
", "") if ".
" in operation: flags += "|INSTR_FORMAT_FLAG_VFP_DATA_SIZE" operation = operation.replace(".
", "") if "" in operation: flags += "|INSTR_FORMAT_FLAG_CONDITIONAL" if "." in operation: size = operation.split("")[1].split()[0][1:].upper() if size in ["F16", "F32", "F64"]: flags += "|INSTR_FORMAT_FLAG_" + size operation = operation.replace("", "") if "{s}" in operation: flags += "|INSTR_FORMAT_FLAG_OPTIONAL_STATUS" operation = operation.replace("{s}", "") if "" in operation: flags += "|INSTR_FORMAT_FLAG_EFFECT" operation = operation.replace("", "") if "" in operation: flags += "|INSTR_FORMAT_FLAG_MASK" operation = operation.replace("", "") if ".w" in operation: flags += "|INSTR_FORMAT_FLAG_WIDE" operation = operation.replace(".w", "") if "{ia}" in operation: flags += "|INSTR_FORMAT_FLAG_INCREMENT_AFTER" operation = operation.replace("{ia}", "") if "{}" in operation: flags += "|INSTR_FORMAT_FLAG_AMODE" operation = operation.replace("{}", "") mgr.add('{ /* %s */' % fmt) mgr.tab() mgr.add('"%s", /* .operation (const char *) */' % operation) mgr.add('%s, /* .operationFlags (uint32_t) */' % flags) mgr.add('{/* .operands (instruction_operand_format) */') mgr.tab() i = 0 operandCount = 0 # operands is the half of the format string following the first whitespace # eg: MOV ,,# # # then operation = 'MOV' # then format = ',,# #print(' operation: %s' % operation) #print('operandsStr: %s' % operandsStr) # split the string into operands operands = [] tok_regexs = [r'^<.*?>(!|{!})?', r'^#<\+/-><.*?>', r'^#<.*?>', \ r'^{.*?}', r'^\[.*?\]!?', r'^\w+({!})?', r'^#\d+'] while operandsStr: did_split = False if operandsStr[0] == ',': operandsStr = operandsStr[1:] continue for regex in tok_regexs: m = re.match(regex, operandsStr) if m: operands.append(m.group(0)) operandsStr = operandsStr[len(m.group(0)):] did_split = True break if not did_split: raise Exception('don\'t know how to split next operand on: %s' % operandsStr) # loop over operands for operand in operands: wb_id = ['WRITEBACK_NO', 'WRITEBACK_YES'][operand[-1]=='!'] #print(' operand: %s' % operand) # # Rn # if operand == "[]": mgr.add('{OPERAND_FORMAT_MEMORY_ONE_REG,FIELD_Rn,FIELD_UNINIT,"","",%s},' % wb_id) continue m = re.match(r'^\[,#<\+/-><(.*)>]!?$', operand) if m: name = m.group(1) mgr.add('{OPERAND_FORMAT_MEMORY_ONE_REG_ADD_IMM,FIELD_Rn,FIELD_%s,"","",%s},' % (name, wb_id)) continue if operand.startswith('[,#]'): mgr.add('{OPERAND_FORMAT_MEMORY_ONE_REG_ALIGNED,FIELD_Rn,FIELD_UNINIT,"","",%s},' % wb_id) continue m = re.match(r'^\[,#<(.*)>\]!?$', operand) if m: name = m.group(1) mgr.add('{OPERAND_FORMAT_MEMORY_ONE_REG_IMM,FIELD_Rn,FIELD_%s,"","",%s},' % (name, wb_id)) continue m = re.match(r'^\[,#-<(.*)>\]!?$', operand) if m: name = m.group(1) mgr.add('{OPERAND_FORMAT_MEMORY_ONE_REG_NEG_IMM,FIELD_Rn,FIELD_%s,"","",%s},' % (name, wb_id)) continue m = re.match(r'^\[{,#<\+/-><(.*)>}\]!?', operand) if m: name = m.group(1) mgr.add('{OPERAND_FORMAT_MEMORY_ONE_REG_OPTIONAL_ADD_IMM,FIELD_Rn,FIELD_%s,"","",%s},' % (name, wb_id)) continue m = re.match(r'^\[{,#<(.*)>}\]$', operand) if m: name = m.group(1) mgr.add('{OPERAND_FORMAT_MEMORY_ONE_REG_OPTIONAL_IMM,FIELD_Rn,FIELD_%s,"","",%s},' % (name, wb_id)) continue if operand.startswith("[,]"): if i < len(operand) and operand[i] == "!": mgr.add('{OPERAND_FORMAT_MEMORY_TWO_REG,FIELD_Rn,FIELD_Rm,"","",WRITEBACK_YES},') else: mgr.add('{OPERAND_FORMAT_MEMORY_TWO_REG,FIELD_Rn,FIELD_Rm,"","",WRITEBACK_NO},') continue if operand.startswith("[,{,}]"): if i < len(operand) and operand[i] == "!": mgr.add('{OPERAND_FORMAT_MEMORY_TWO_REG_SHIFT,FIELD_Rn,FIELD_Rm,"","",WRITEBACK_YES},') else: mgr.add('{OPERAND_FORMAT_MEMORY_TWO_REG_SHIFT,FIELD_Rn,FIELD_Rm,"","",WRITEBACK_NO},') continue if operand.startswith("[,,LSL #1]"): if i < len(operand) and operand[i] == "!": mgr.add('{OPERAND_FORMAT_MEMORY_TWO_REG_LSL_ONE,FIELD_Rn,FIELD_Rm,"","",WRITEBACK_YES},') else: mgr.add('{OPERAND_FORMAT_MEMORY_TWO_REG_LSL_ONE,FIELD_Rn,FIELD_Rm,"","",WRITEBACK_NO},') continue if operand.startswith("!"): mgr.add('{OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_YES},') continue if operand.startswith("{!}"): mgr.add('{OPERAND_FORMAT_REG,FIELD_Rn,FIELD_UNINIT,"","",WRITEBACK_OPTIONAL},') continue # # SP # m = re.match(r'^\[SP,#<(.*)>\]$', operand) if m: name = m.group(1) mgr.add('{OPERAND_FORMAT_MEMORY_SP_IMM,FIELD_%s,FIELD_UNINIT,"","",%s},' % (name, wb_id)) continue m = re.match(r'^\[SP{,#<(.*)>}\]', operand) if m: name = m.group(1) mgr.add('{OPERAND_FORMAT_MEMORY_SP_OPTIONAL_IMM,FIELD_%s,FIELD_UNINIT,"","",%s},' % (name, wb_id)) continue if operand.startswith("SP{!}"): mgr.add('{OPERAND_FORMAT_SP,FIELD_UNINIT,FIELD_UNINIT,"sp","",WRITEBACK_OPTIONAL},') continue if operand.startswith("SP"): mgr.add('{OPERAND_FORMAT_SP,FIELD_UNINIT,FIELD_UNINIT,"sp","",WRITEBACK_NO},') continue # # PC # if operand.startswith("[PC]"): mgr.add('{OPERAND_FORMAT_MEMORY_PC,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO},') continue if operand.startswith("PC"): mgr.add('{OPERAND_FORMAT_PC,FIELD_UNINIT,FIELD_UNINIT,"pc","",WRITEBACK_NO},') continue if operand.startswith("LSL #1"): mgr.add('{OPERAND_FORMAT_LSL_ONE,FIELD_UNINIT,FIELD_UNINIT,"lsl #1","",WRITEBACK_NO},') continue if operand.startswith("#0"): mgr.add('{OPERAND_FORMAT_ZERO,FIELD_UNINIT,FIELD_UNINIT,"#0","",WRITEBACK_NO},') continue if operand.startswith(""): mgr.add('{OPERAND_FORMAT_BARRIER_OPTION,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO},') continue if operand.startswith("LR"): mgr.add('{OPERAND_FORMAT_LR,FIELD_UNINIT,FIELD_UNINIT,"lr","",WRITEBACK_NO},') continue if operand.startswith("#"): mgr.add('{OPERAND_FORMAT_IMM64,FIELD_UNINIT,FIELD_UNINIT,"#","",WRITEBACK_NO},') continue m = re.match(r'^<(imm.*)>$', operand) if m: name = m.group(1) mgr.add('{OPERAND_FORMAT_IMM,FIELD_%s,FIELD_UNINIT,"#","",WRITEBACK_NO},' % (name)) continue if operand[i:4] in ['', '', '', '
', '', '', '', '', '']: name = operand[2] mgr.add('{OPERAND_FORMAT_REG_FP,FIELD_%s,FIELD_UNINIT,"%s","",WRITEBACK_OPTIONAL},' % (name, operand[1].lower())) continue if operand[i:7] in ['', '', '', '', '', '', '', '', '']: name = operand[2] mgr.add('{OPERAND_FORMAT_REG_INDEX,FIELD_%s,FIELD_x,"%s","",WRITEBACK_OPTIONAL},' % (name, operand[1].lower())) continue if operand.startswith(''): mgr.add('{OPERAND_FORMAT_FPSCR,FIELD_FPSCR,FIELD_UNINIT,"","",WRITEBACK_OPTIONAL},') continue if operand.startswith(''): mgr.add('{OPERAND_FORMAT_RT_MRC,FIELD_Rt_mrc,FIELD_UNINIT,"","",WRITEBACK_NO},') continue if operand.startswith('apsr'): mgr.add('{OPERAND_FORMAT_SPEC_REG,FIELD_UNINIT,FIELD_UNINIT,"apsr","",WRITEBACK_NO},') continue # here is generic register catcher # make sure any special register cases (eg: "" you have come before this) m = re.match(r'^<(R.*)>$', operand) if m: name = m.group(1) mgr.add('{OPERAND_FORMAT_REG,FIELD_%s,FIELD_UNINIT,"","",WRITEBACK_NO},' % name) continue if operand.startswith(""): mgr.add('{OPERAND_FORMAT_COPROC,FIELD_coproc,FIELD_UNINIT,"","",WRITEBACK_NO},') continue m = re.match(r'^<(CR.*)>$', operand) if m: name = m.group(1) mgr.add('{OPERAND_FORMAT_COPROC_REG,FIELD_%s,FIELD_UNINIT,"","",WRITEBACK_NO},' % name) continue if operand.startswith(""): mgr.add('{OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","",WRITEBACK_NO},') continue if operand.startswith(""): mgr.add('{OPERAND_FORMAT_REGISTERS,FIELD_registers,FIELD_UNINIT,"","[]",WRITEBACK_NO},') continue if operand.startswith(""): mgr.add('{OPERAND_FORMAT_REGISTERS_INDEXED,FIELD_registers_indexed,FIELD_UNINIT,"","",WRITEBACK_NO},') continue if operand.startswith(""): mgr.add('{OPERAND_FORMAT_LIST,FIELD_list,FIELD_UNINIT,"","",WRITEBACK_NO},') continue if operand.startswith(""): mgr.add('{OPERAND_FORMAT_ENDIAN,FIELD_E,FIELD_UNINIT,"","",WRITEBACK_NO},') continue if operand.startswith("{,}"): mgr.add('{OPERAND_FORMAT_SHIFT,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO},') continue if operand.startswith('{,}'): mgr.add('{OPERAND_FORMAT_ROTATION,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO},') continue if operand.startswith(""): mgr.add('{OPERAND_FORMAT_EFFECT,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO},') continue if operand.startswith(""): mgr.add('{OPERAND_FORMAT_IFLAGS,FIELD_UNINIT,FIELD_UNINIT,"","",WRITEBACK_NO},') continue if operand.startswith(""): mgr.add('{OPERAND_FORMAT_FIRSTCOND,FIELD_firstcond,FIELD_UNINIT,"","",WRITEBACK_NO},') continue if operand.startswith("