├── LICENSE ├── README.md └── or1k.py /LICENSE: -------------------------------------------------------------------------------- 1 | Creative Commons Legal Code 2 | 3 | CC0 1.0 Universal 4 | 5 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE 6 | LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN 7 | ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS 8 | INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES 9 | REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS 10 | PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM 11 | THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED 12 | HEREUNDER. 13 | 14 | Statement of Purpose 15 | 16 | The laws of most jurisdictions throughout the world automatically confer 17 | exclusive Copyright and Related Rights (defined below) upon the creator 18 | and subsequent owner(s) (each and all, an "owner") of an original work of 19 | authorship and/or a database (each, a "Work"). 20 | 21 | Certain owners wish to permanently relinquish those rights to a Work for 22 | the purpose of contributing to a commons of creative, cultural and 23 | scientific works ("Commons") that the public can reliably and without fear 24 | of later claims of infringement build upon, modify, incorporate in other 25 | works, reuse and redistribute as freely as possible in any form whatsoever 26 | and for any purposes, including without limitation commercial purposes. 27 | These owners may contribute to the Commons to promote the ideal of a free 28 | culture and the further production of creative, cultural and scientific 29 | works, or to gain reputation or greater distribution for their Work in 30 | part through the use and efforts of others. 31 | 32 | For these and/or other purposes and motivations, and without any 33 | expectation of additional consideration or compensation, the person 34 | associating CC0 with a Work (the "Affirmer"), to the extent that he or she 35 | is an owner of Copyright and Related Rights in the Work, voluntarily 36 | elects to apply CC0 to the Work and publicly distribute the Work under its 37 | terms, with knowledge of his or her Copyright and Related Rights in the 38 | Work and the meaning and intended legal effect of CC0 on those rights. 39 | 40 | 1. Copyright and Related Rights. A Work made available under CC0 may be 41 | protected by copyright and related or neighboring rights ("Copyright and 42 | Related Rights"). Copyright and Related Rights include, but are not 43 | limited to, the following: 44 | 45 | i. the right to reproduce, adapt, distribute, perform, display, 46 | communicate, and translate a Work; 47 | ii. moral rights retained by the original author(s) and/or performer(s); 48 | iii. publicity and privacy rights pertaining to a person's image or 49 | likeness depicted in a Work; 50 | iv. rights protecting against unfair competition in regards to a Work, 51 | subject to the limitations in paragraph 4(a), below; 52 | v. rights protecting the extraction, dissemination, use and reuse of data 53 | in a Work; 54 | vi. database rights (such as those arising under Directive 96/9/EC of the 55 | European Parliament and of the Council of 11 March 1996 on the legal 56 | protection of databases, and under any national implementation 57 | thereof, including any amended or successor version of such 58 | directive); and 59 | vii. other similar, equivalent or corresponding rights throughout the 60 | world based on applicable law or treaty, and any national 61 | implementations thereof. 62 | 63 | 2. Waiver. To the greatest extent permitted by, but not in contravention 64 | of, applicable law, Affirmer hereby overtly, fully, permanently, 65 | irrevocably and unconditionally waives, abandons, and surrenders all of 66 | Affirmer's Copyright and Related Rights and associated claims and causes 67 | of action, whether now known or unknown (including existing as well as 68 | future claims and causes of action), in the Work (i) in all territories 69 | worldwide, (ii) for the maximum duration provided by applicable law or 70 | treaty (including future time extensions), (iii) in any current or future 71 | medium and for any number of copies, and (iv) for any purpose whatsoever, 72 | including without limitation commercial, advertising or promotional 73 | purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each 74 | member of the public at large and to the detriment of Affirmer's heirs and 75 | successors, fully intending that such Waiver shall not be subject to 76 | revocation, rescission, cancellation, termination, or any other legal or 77 | equitable action to disrupt the quiet enjoyment of the Work by the public 78 | as contemplated by Affirmer's express Statement of Purpose. 79 | 80 | 3. Public License Fallback. Should any part of the Waiver for any reason 81 | be judged legally invalid or ineffective under applicable law, then the 82 | Waiver shall be preserved to the maximum extent permitted taking into 83 | account Affirmer's express Statement of Purpose. In addition, to the 84 | extent the Waiver is so judged Affirmer hereby grants to each affected 85 | person a royalty-free, non transferable, non sublicensable, non exclusive, 86 | irrevocable and unconditional license to exercise Affirmer's Copyright and 87 | Related Rights in the Work (i) in all territories worldwide, (ii) for the 88 | maximum duration provided by applicable law or treaty (including future 89 | time extensions), (iii) in any current or future medium and for any number 90 | of copies, and (iv) for any purpose whatsoever, including without 91 | limitation commercial, advertising or promotional purposes (the 92 | "License"). The License shall be deemed effective as of the date CC0 was 93 | applied by Affirmer to the Work. Should any part of the License for any 94 | reason be judged legally invalid or ineffective under applicable law, such 95 | partial invalidity or ineffectiveness shall not invalidate the remainder 96 | of the License, and in such case Affirmer hereby affirms that he or she 97 | will not (i) exercise any of his or her remaining Copyright and Related 98 | Rights in the Work or (ii) assert any associated claims and causes of 99 | action with respect to the Work, in either case contrary to Affirmer's 100 | express Statement of Purpose. 101 | 102 | 4. Limitations and Disclaimers. 103 | 104 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 105 | surrendered, licensed or otherwise affected by this document. 106 | b. Affirmer offers the Work as-is and makes no representations or 107 | warranties of any kind concerning the Work, express, implied, 108 | statutory or otherwise, including without limitation warranties of 109 | title, merchantability, fitness for a particular purpose, non 110 | infringement, or the absence of latent or other defects, accuracy, or 111 | the present or absence of errors, whether or not discoverable, all to 112 | the greatest extent permissible under applicable law. 113 | c. Affirmer disclaims responsibility for clearing rights of other persons 114 | that may apply to the Work or any use thereof, including without 115 | limitation any person's Copyright and Related Rights in the Work. 116 | Further, Affirmer disclaims responsibility for obtaining any necessary 117 | consents, permissions or other rights required for any use of the 118 | Work. 119 | d. Affirmer understands and acknowledges that Creative Commons is not a 120 | party to this document and has no duty or obligation with respect to 121 | this CC0 or use of the Work. 122 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## OpenRISC 1000 support for IDA 7.x 2 | 3 | Place the `or1k.py` in the `procs` directory. 4 | If you don't see "OpenRISC 1000 (or1k)" in the CPU selection, then check if Python support is working in IDA. 5 | 6 | You can switch between delay-slot and no-delay mode by changing the value of the `ND` in the dialog box displayed by pressing Alt-G. 7 | 8 | * A non-zero value of `ND` means no delay. 9 | 10 | * On the CPU this mode is controlled by the `ND` bit of the special-purpose register `CPUCFGR`. 11 | 12 | -------------------------------------------------------------------------------- /or1k.py: -------------------------------------------------------------------------------- 1 | # ---------------------------------------------------------------------- 2 | # OpenRISC 1000 processor module 3 | # Copyright (c) 2023 Ilya Kurdyukov 4 | # 5 | # Compatible with IDA 7.x and possibly later versions. 6 | 7 | import sys 8 | from ida_idp import * 9 | from ida_ua import * 10 | from ida_lines import * 11 | from ida_problems import * 12 | from ida_xref import * 13 | from ida_idaapi import * 14 | from ida_bytes import * 15 | import ida_segment 16 | import ida_segregs 17 | 18 | if sys.version_info.major < 3: 19 | range = xrange 20 | 21 | # sign extend b low bits in x 22 | def SIGNEXT(x, b): 23 | m = 1 << (b - 1) 24 | return (x & (m - 1)) - (x & m) 25 | 26 | # No Delay-Slot 27 | # 0: CPU executes delay slot of jump/branch instructions before taking jump/branch 28 | # 1: CPU does not execute instructions in delay slot if taking jump/branch 29 | DEFAULT_ND = 1 30 | 31 | # values for insn_t.auxpref 32 | AUX_LO = 1 # lo(imm) 33 | 34 | FIND_MOVHI_RANGE = 16 35 | 36 | DECODE_RD_NONE = 0 37 | DECODE_RD_CUST = -1 38 | DECODE_RD_JUMP = -2 39 | DECODE_RD_CALL = -3 40 | 41 | # Registers that are preserved across calls. 42 | CALLEE_SAVED_MASK = 0x55554407 43 | 44 | # ---------------------------------------------------------------------- 45 | class or1k_processor_t(processor_t): 46 | """ 47 | Processor module classes must derive from processor_t 48 | """ 49 | 50 | # IDP id ( Numbers above 0x8000 are reserved for the third-party modules) 51 | # elf.h: EM_OPENRISC = 92 52 | id = 0x8000 + 92 53 | 54 | # Processor features 55 | flag = PR_SEGS | PR_USE32 | PR_DEFSEG32 | PR_RNAMESOK | PRN_HEX | PR_SGROTHER | PR_DELAYED 56 | 57 | # Number of bits in a byte for code segments (usually 8) 58 | # IDA supports values up to 32 bits (64 for IDA64) 59 | cnbits = 8 60 | 61 | # Number of bits in a byte for non-code segments (usually 8) 62 | # IDA supports values up to 32 bits (64 for IDA64) 63 | dnbits = 8 64 | 65 | # short processor names 66 | # Each name should be shorter than 9 characters 67 | psnames = ["or1k"] 68 | 69 | # long processor names 70 | # No restriction on name lengthes. 71 | plnames = ["OpenRISC 1000"] 72 | 73 | # size of a segment register in bytes 74 | segreg_size = 0 75 | 76 | # 77 | # Number of digits in floating numbers after the decimal point. 78 | # If an element of this array equals 0, then the corresponding 79 | # floating point data is not used for the processor. 80 | # This array is used to align numbers in the output. 81 | # real_width[0] - number of digits for short floats (only PDP-11 has them) 82 | # real_width[1] - number of digits for "float" 83 | # real_width[2] - number of digits for "double" 84 | # real_width[3] - number of digits for "long double" 85 | # Example: IBM PC module has { 0,7,15,19 } 86 | # 87 | # (optional) 88 | real_width = (0, 7, 15, 0) 89 | 90 | 91 | # only one assembler is supported 92 | assembler = { 93 | # flag 94 | "flag": ASH_HEXF3 | ASD_DECF0 | ASO_OCTF1 | ASB_BINF3 | AS_N2CHR, 95 | 96 | # user defined flags (local only for IDP) (optional) 97 | "uflag": 0, 98 | 99 | # Assembler name (displayed in menus) 100 | "name": "OpenRISC 1000 assembler", 101 | 102 | # array of automatically generated header lines they appear at the start of disassembled text (optional) 103 | # 'header': [".or1k"], 104 | 105 | # org directive 106 | "origin": ".org", 107 | 108 | # end directive 109 | "end": ".end", 110 | 111 | # comment string (see also cmnt2) 112 | "cmnt": "#", 113 | 114 | # ASCII string delimiter 115 | 'ascsep': "\"", 116 | 117 | # ASCII char constant delimiter 118 | "accsep": "'", 119 | 120 | # ASCII special chars (they can't appear in character and ascii constants) 121 | 'esccodes': "\"'", 122 | 123 | # 124 | # Data representation (db,dw,...): 125 | # 126 | # ASCII string directive 127 | 'a_ascii': ".char", 128 | 129 | # byte directive 130 | 'a_byte': ".byte", 131 | 132 | # word directive 133 | 'a_word': ".half", 134 | 135 | # remove if not allowed 136 | 'a_dword': ".word", 137 | 138 | # remove if not allowed 139 | 'a_qword': ".dword", 140 | 141 | # float; 4bytes; remove if not allowed 142 | 'a_float': ".float", 143 | 144 | # double; 8bytes; NULL if not allowed 145 | 'a_double': ".double", 146 | 147 | # uninitialized data directive (should include '%s' for the size of data) 148 | 'a_bss': ".space %s", 149 | 150 | # 'equ' Used if AS_UNEQU is set (optional) 151 | 'a_equ': ".equ", 152 | 153 | # 'seg ' prefix (example: push seg seg001) 154 | 'a_seg': "seg", 155 | 156 | # current IP (instruction pointer) symbol in assembler 157 | 'a_curip': ".", 158 | 159 | # "public" name keyword. NULL-gen default, ""-do not generate 160 | 'a_public': "", 161 | 162 | # "weak" name keyword. NULL-gen default, ""-do not generate 163 | 'a_weak': "", 164 | 165 | # "extrn" name keyword 166 | 'a_extrn': ".extern", 167 | 168 | # "comm" (communal variable) 169 | "a_comdef": "", 170 | 171 | # "align" keyword 172 | "a_align": ".align", 173 | 174 | # Left and right braces used in complex expressions 175 | "lbrace": "(", 176 | "rbrace": ")", 177 | 178 | # % mod assembler time operation 179 | "a_mod": "%", 180 | 181 | # & bit and assembler time operation 182 | "a_band": "&", 183 | 184 | # | bit or assembler time operation 185 | "a_bor": "|", 186 | 187 | # ^ bit xor assembler time operation 188 | "a_xor": "^", 189 | 190 | # ~ bit not assembler time operation 191 | "a_bnot": "~", 192 | 193 | # << shift left assembler time operation 194 | "a_shl": "<<", 195 | 196 | # >> shift right assembler time operation 197 | "a_shr": ">>", 198 | 199 | # size of type (format string) (optional) 200 | "a_sizeof_fmt": "size %s", 201 | 202 | 'flag2': 0, 203 | 204 | # the include directive (format string) (optional) 205 | 'a_include_fmt': '.include "%s"', 206 | } 207 | 208 | # ---------------------------------------------------------------------- 209 | def notify_get_autocmt(self, insn): 210 | """ 211 | Get instruction comment. 'insn' describes the instruction in question 212 | @return: None or the comment string 213 | """ 214 | if 'cmt' in self.instruc[insn.itype]: 215 | return self.instruc[insn.itype]['cmt'] 216 | 217 | # ---------------------------------------------------------------------- 218 | 219 | maptbl_jump = ['l.j', 'l.jal', 'l.adrp', 'l.bnf', 'l.bf'] 220 | maptbl_shift = ['l.sll', 'l.srl', 'l.sra', 'l.ror'] 221 | maptbl_load = ['l.lf', 'l.lwa', 'l.cust1', 'l.cust2', 'l.cust3', 'l.cust4', 222 | 'l.ld', 'l.lwz', 'l.lws', 'l.lbz', 'l.lbs', 'l.lhz', 'l.lhs'] 223 | maptbl_store = ['l.swa', 'l.sd', 'l.sw', 'l.sb', 'l.sh'] 224 | maptbl_27 = ['l.addi', 'l.addic', 'l.andi', 'l.ori', 'l.xori', 'l.muli', 'l.mfspr'] 225 | maptbl_38 = ['l.add', 'l.addc', 'l.sub', 'l.and', 'l.or', 'l.xor', 'l.mul', 'l.muld', 226 | '', 'l.div', 'l.divu', 'l.mulu', 'l.muldu', '', 'l.cmov', ''] 227 | maptbl_ext = ['l.exths', 'l.extbs', 'l.exthz', 'l.extbz', 'l.extws', 'l.extwz'] 228 | 229 | maptbl_setflag = { 230 | 0x00: 'l.sfeq', 231 | 0x01: 'l.sfne', 232 | 0x02: 'l.sfgtu', 233 | 0x03: 'l.sfgeu', 234 | 0x04: 'l.sfltu', 235 | 0x05: 'l.sfleu', 236 | 0x0a: 'l.sfgts', 237 | 0x0b: 'l.sfges', 238 | 0x0c: 'l.sflts', 239 | 0x0d: 'l.sfles' 240 | } 241 | 242 | maptbl_float = { 243 | 0x00: 'lf.add.s', 244 | 0x01: 'lf.sub.s', 245 | 0x02: 'lf.mul.s', 246 | 0x03: 'lf.div.s', 247 | 0x04: 'lf.itof.s', 248 | 0x05: 'lf.ftoi.s', 249 | 0x06: 'lf.rem.s', # removed in 1.3 250 | 0x07: 'lf.madd.s', 251 | 0x08: 'lf.sfeq.s', 252 | 0x09: 'lf.sfne.s', 253 | 0x0a: 'lf.sfgt.s', 254 | 0x0b: 'lf.sfge.s', 255 | 0x0c: 'lf.sflt.s', 256 | 0x0d: 'lf.sfle.s', 257 | 258 | 0x10: 'lf.add.d', 259 | 0x11: 'lf.sub.d', 260 | 0x12: 'lf.mul.d', 261 | 0x13: 'lf.div.d', 262 | 0x14: 'lf.itof.d', 263 | 0x15: 'lf.ftoi.d', 264 | 0x16: 'lf.rem.d', # removed in 1.3 265 | 0x17: 'lf.madd.d', 266 | 0x18: 'lf.sfeq.d', 267 | 0x19: 'lf.sfne.d', 268 | 0x1a: 'lf.sfgt.d', 269 | 0x1b: 'lf.sfge.d', 270 | 0x1c: 'lf.sflt.d', 271 | 0x1d: 'lf.sfle.d', 272 | 273 | # new in 1.3 274 | 0x28: 'lf.sfueq.s', 275 | 0x29: 'lf.sfune.s', 276 | 0x2a: 'lf.sfugt.s', 277 | 0x2b: 'lf.sfuge.s', 278 | 0x2c: 'lf.sfult.s', 279 | 0x2d: 'lf.sfule.s', 280 | 0x2e: 'lf.sfun.s', 281 | 0x34: 'lf.stod.d', 282 | 0x35: 'lf.dtos.d', 283 | 0x38: 'lf.sfueq.d', 284 | 0x39: 'lf.sfune.d', 285 | 0x3a: 'lf.sfugt.d', 286 | 0x3b: 'lf.sfuge.d', 287 | 0x3c: 'lf.sfult.d', 288 | 0x3d: 'lf.sfule.d', 289 | 0x3e: 'lf.sfun.d' 290 | } 291 | 292 | maptbl_vec = { 293 | 0x10: 'lv.all_eq.b', 294 | 0x11: 'lv.all_eq.h', 295 | 0x12: 'lv.all_ge.b', 296 | 0x13: 'lv.all_ge.h', 297 | 0x14: 'lv.all_gt.b', 298 | 0x15: 'lv.all_gt.h', 299 | 0x16: 'lv.all_le.b', 300 | 0x17: 'lv.all_le.h', 301 | 0x18: 'lv.all_lt.b', 302 | 0x19: 'lv.all_lt.h', 303 | 0x1a: 'lv.all_ne.b', 304 | 0x1b: 'lv.all_ne.h', 305 | 0x20: 'lv.any_eq.b', 306 | 0x21: 'lv.any_eq.h', 307 | 0x22: 'lv.any_ge.b', 308 | 0x23: 'lv.any_ge.h', 309 | 0x24: 'lv.any_gt.b', 310 | 0x25: 'lv.any_gt.h', 311 | 0x26: 'lv.any_le.b', 312 | 0x27: 'lv.any_le.h', 313 | 0x28: 'lv.any_lt.b', 314 | 0x29: 'lv.any_lt.h', 315 | 0x2a: 'lv.any_ne.b', 316 | 0x2b: 'lv.any_ne.h', 317 | 0x30: 'lv.add.b', 318 | 0x31: 'lv.add.h', 319 | 0x32: 'lv.adds.b', 320 | 0x33: 'lv.adds.h', 321 | 0x34: 'lv.addu.b', 322 | 0x35: 'lv.addu.h', 323 | 0x36: 'lv.addus.b', 324 | 0x37: 'lv.addus.h', 325 | 0x38: 'lv.and', 326 | 0x39: 'lv.avg.b', 327 | 0x3a: 'lv.avg.h', 328 | 0x40: 'lv.cmp_eq.b', 329 | 0x41: 'lv.cmp_eq.h', 330 | 0x42: 'lv.cmp_ge.b', 331 | 0x43: 'lv.cmp_ge.h', 332 | 0x44: 'lv.cmp_gt.b', 333 | 0x45: 'lv.cmp_gt.h', 334 | 0x46: 'lv.cmp_le.b', 335 | 0x47: 'lv.cmp_le.h', 336 | 0x48: 'lv.cmp_lt.b', 337 | 0x49: 'lv.cmp_lt.h', 338 | 0x4a: 'lv.cmp_ne.b', 339 | 0x4b: 'lv.cmp_ne.h', 340 | 0x54: 'lv.madds.h', 341 | 0x55: 'lv.max.b', 342 | 0x56: 'lv.max.h', 343 | 0x57: 'lv.merge.b', 344 | 0x58: 'lv.merge.h', 345 | 0x59: 'lv.min.b', 346 | 0x5a: 'lv.min.h', 347 | 0x5b: 'lv.msubs.h', 348 | 0x5c: 'lv.muls.h', 349 | 0x5d: 'lv.nand', 350 | 0x5e: 'lv.nor', 351 | 0x5f: 'lv.or', 352 | 0x60: 'lv.pack.b', 353 | 0x61: 'lv.pack.h', 354 | 0x62: 'lv.packs.b', 355 | 0x63: 'lv.packs.h', 356 | 0x64: 'lv.packus.b', 357 | 0x65: 'lv.packus.h', 358 | 0x66: 'lv.perm.n', 359 | 0x67: 'lv.rl.b', 360 | 0x68: 'lv.rl.h', 361 | 0x6b: 'lv.sll', 362 | 0x69: 'lv.sll.b', 363 | 0x6a: 'lv.sll.h', 364 | 0x6e: 'lv.sra.b', 365 | 0x6f: 'lv.sra.h', 366 | 0x70: 'lv.srl', 367 | 0x6c: 'lv.srl.b', 368 | 0x6d: 'lv.srl.h', 369 | 0x71: 'lv.sub.b', 370 | 0x72: 'lv.sub.h', 371 | 0x73: 'lv.subs.b', 372 | 0x74: 'lv.subs.h', 373 | 0x75: 'lv.subu.b', 374 | 0x76: 'lv.subu.h', 375 | 0x77: 'lv.subus.b', 376 | 0x78: 'lv.subus.h', 377 | 0x79: 'lv.unpack.b', 378 | 0x7a: 'lv.unpack.h', 379 | 0x7b: 'lv.xor' 380 | } 381 | 382 | def notify_ana(self, insn): 383 | """ 384 | Decodes an instruction into 'insn'. 385 | Returns: insn.size (=the size of the decoded instruction) or zero 386 | """ 387 | if insn.ea & 3 != 0: 388 | return 0 389 | raw = insn.get_next_dword() 390 | opc = (raw >> 26) & 0x3f 391 | rD = (raw >> 21) & 0x1f 392 | rA = (raw >> 16) & 0x1f 393 | rB = (raw >> 11) & 0x1f 394 | 395 | if opc < 0x05: 396 | insn.itype = self.maptbl_jump[opc] 397 | if opc == 0x02: 398 | insn.Op1.type = o_reg 399 | insn.Op1.reg = rD 400 | insn.Op2.type = o_imm 401 | insn.Op2.value = raw & 0x1fffff 402 | else: 403 | addr = raw & 0x3ffffff 404 | insn.Op1.type = o_near 405 | insn.Op1.addr = (insn.ea + SIGNEXT(addr, 26) * 4) & 0xffffffff 406 | 407 | # raw 0x05 408 | elif raw >> 24 & 0xff == 0x15: 409 | insn.itype = self.name2icode['l.nop'] 410 | insn.Op1.type = o_imm 411 | insn.Op1.value = raw & 0xffff 412 | 413 | elif opc == 0x06: 414 | insn.Op1.type = o_reg 415 | insn.Op1.reg = rD 416 | if raw & 0x10000 == 0: 417 | insn.itype = self.name2icode['l.movhi'] 418 | insn.Op2.type = o_imm 419 | insn.Op2.value = raw & 0xffff 420 | else: 421 | if raw & 0xffff != 0: 422 | return 0 423 | insn.itype = self.name2icode['l.macrc'] 424 | 425 | elif opc == 0x08: 426 | raw &= 0xffffffff 427 | if raw >> 16 == 0x2000: 428 | insn.itype = self.name2icode['l.sys'] 429 | insn.Op1.type = o_imm 430 | insn.Op1.value = raw & 0xffff 431 | elif raw >> 16 == 0x2100: 432 | insn.itype = self.name2icode['l.trap'] 433 | insn.Op1.type = o_imm 434 | insn.Op1.value = raw & 0xffff 435 | elif raw == 0x22000000: 436 | insn.itype = self.name2icode['l.msync'] 437 | elif raw == 0x22800000: 438 | insn.itype = self.name2icode['l.psync'] 439 | elif raw == 0x23000000: 440 | insn.itype = self.name2icode['l.csync'] 441 | else: 442 | return 0 443 | 444 | elif opc == 0x09: 445 | insn.itype = self.name2icode['l.rfe'] 446 | elif opc == 0x11: 447 | insn.itype = self.name2icode['l.jr'] 448 | insn.Op1.type = o_reg 449 | insn.Op1.reg = rB 450 | elif opc == 0x12: 451 | insn.itype = self.name2icode['l.jalr'] 452 | insn.Op1.type = o_reg 453 | insn.Op1.reg = rB 454 | elif opc == 0x13: 455 | insn.itype = self.name2icode['l.maci'] 456 | insn.Op1.type = o_reg 457 | insn.Op1.reg = rA 458 | insn.Op2.type = o_imm 459 | insn.Op2.value = SIGNEXT(raw, 16) 460 | 461 | # find 462 | elif opc == 0x38 and raw & 0x20f == 0xf: 463 | insn.Op1.type = o_reg 464 | insn.Op1.reg = rD 465 | insn.Op2.type = o_reg 466 | insn.Op2.reg = rA 467 | if raw & 0x300 == 0: 468 | insn.itype = self.name2icode['l.ff1'] 469 | elif raw & 0x300 == 0x100: 470 | insn.itype = self.name2icode['l.fl1'] 471 | 472 | # arith 473 | elif opc == 0x38 and raw & 0x300 == 0: 474 | insn.Op1.type = o_reg 475 | insn.Op1.reg = rD 476 | insn.Op2.type = o_reg 477 | insn.Op2.reg = rA 478 | opc2 = raw & 0xf 479 | mask = 1 << opc2 480 | # 0, 1, 2, 3, 4, 5, 8, 14 481 | if 0x413f & mask != 0: 482 | insn.Op3.type = o_reg 483 | insn.Op3.reg = rB 484 | if opc2 != 0x8: 485 | insn.itype = self.maptbl_38[opc2] 486 | else: 487 | insn.itype = self.maptbl_shift[raw >> 6 & 3] 488 | # 12, 13 489 | else: 490 | opc3 = (raw >> 6 & 3) | opc2 << 2 491 | if opc3 < 0x30 or opc3 >= 0x36: 492 | return 0 493 | insn.itype = self.maptbl_ext[opc3 - 0x30] 494 | 495 | # mul/div 496 | elif opc == 0x38 and raw & 0x300 == 0x300: 497 | opc2 = raw & 0xf 498 | mask = 1 << opc2 499 | # 6, 7, 9, a, b, c 500 | if 0x1ec0 & mask == 0: 501 | return 0 502 | insn.itype = self.maptbl_38[opc2] 503 | # 0x7, 0xc: l.muld, l.muldu 504 | if 0x1080 & mask != 0: 505 | insn.Op1.type = o_reg 506 | insn.Op1.reg = rA 507 | insn.Op2.type = o_reg 508 | insn.Op2.reg = rB 509 | else: 510 | insn.Op1.type = o_reg 511 | insn.Op1.reg = rD 512 | insn.Op2.type = o_reg 513 | insn.Op2.reg = rA 514 | insn.Op3.type = o_reg 515 | insn.Op3.reg = rB 516 | 517 | # arith imm16 518 | elif opc >= 0x27 and opc <= 0x2e: 519 | insn.Op1.type = o_reg 520 | insn.Op1.reg = rD 521 | insn.Op2.type = o_reg 522 | insn.Op2.reg = rA 523 | insn.Op3.type = o_imm 524 | if opc == 0x2e: 525 | insn.itype = self.maptbl_shift_imm[raw >> 6 & 3] 526 | insn.Op3.value = raw & 0x3f 527 | else: 528 | insn.itype = self.maptbl_27[opc - 0x27] 529 | # l.addi, l.addic, l.muli 530 | if opc == 0x27 or opc == 0x28 or opc == 0x2c: 531 | insn.Op3.value = SIGNEXT(raw, 16) 532 | else: 533 | insn.Op3.value = raw & 0xffff 534 | 535 | # try to find l.movhi to combine 536 | if insn.itype == self.itype_ori: 537 | self.find_movhi(insn) 538 | 539 | # load 540 | elif opc >= 0x1a and opc <= 0x26: 541 | insn.itype = self.maptbl_load[opc - 0x1a] 542 | if opc < 0x1c or opc > 0x1f: 543 | insn.Op1.type = o_reg 544 | insn.Op1.reg = rD 545 | insn.Op2.type = o_displ 546 | insn.Op2.addr = SIGNEXT(raw, 16) 547 | insn.Op2.reg = rA 548 | 549 | elif opc == 0x30: 550 | insn.itype = self.name2icode['l.mtspr'] 551 | insn.Op1.type = o_reg 552 | insn.Op1.reg = rA 553 | insn.Op2.type = o_reg 554 | insn.Op2.reg = rB 555 | insn.Op3.type = o_imm 556 | insn.Op3.value = (raw & 0x7ff) | (raw >> 10 & 0xf800) 557 | 558 | elif opc == 0x31: 559 | insn.Op1.type = o_reg 560 | insn.Op1.reg = rA 561 | insn.Op2.type = o_reg 562 | insn.Op2.reg = rB 563 | opc2 = raw & 0xf 564 | if opc2 == 1: 565 | insn.itype = self.name2icode['l.mac'] 566 | elif opc2 == 2: 567 | insn.itype = self.name2icode['l.msb'] 568 | elif opc2 == 3: 569 | insn.itype = self.name2icode['l.macu'] 570 | elif opc2 == 4: 571 | insn.itype = self.name2icode['l.msbu'] 572 | else: 573 | return 0 574 | 575 | # set flag imm16 576 | elif opc == 0x2f: 577 | if not rD in self.maptbl_setflag: 578 | return 0 579 | insn.itype = self.maptbl_setflag_imm[rD] 580 | insn.Op1.type = o_reg 581 | insn.Op1.reg = rA 582 | insn.Op2.type = o_imm 583 | insn.Op2.value = SIGNEXT(raw, 16) 584 | # set flag 585 | elif opc == 0x39: 586 | if not rD in self.maptbl_setflag: 587 | return 0 588 | insn.itype = self.maptbl_setflag[rD] 589 | insn.Op1.type = o_reg 590 | insn.Op1.reg = rA 591 | insn.Op2.type = o_reg 592 | insn.Op2.reg = rB 593 | 594 | # store 595 | elif opc >= 0x33 and opc <= 0x37: 596 | insn.itype = self.maptbl_store[opc - 0x33] 597 | addr_imm = (raw & 0x7ff) | (raw >> 10 & 0xf800) 598 | insn.Op1.type = o_displ 599 | insn.Op1.addr = SIGNEXT(addr_imm, 16) 600 | insn.Op1.reg = rA 601 | insn.Op2.type = o_reg 602 | insn.Op2.reg = rB 603 | 604 | # float 605 | elif opc == 0x32: 606 | masked = raw & 0xce 607 | opc2 = raw & 0xff 608 | # lf.sf* 609 | if masked >= 0x08 and masked < 0x0e: 610 | insn.Op1.type = o_reg 611 | insn.Op1.reg = rA 612 | insn.Op2.type = o_reg 613 | insn.Op2.reg = rB 614 | else: 615 | insn.Op1.type = o_reg 616 | insn.Op1.reg = rD 617 | insn.Op2.type = o_reg 618 | insn.Op2.reg = rA 619 | # lf.{i,f,s,d}to* 620 | if masked == 0x04: 621 | if rB != 0: 622 | return 0 623 | else: 624 | insn.Op3.type = o_reg 625 | insn.Op3.reg = rB 626 | 627 | if opc2 in self.maptbl_float: 628 | insn.itype = self.maptbl_float[opc2] 629 | elif opc2 & 0xf0 == 0xd0: 630 | insn.itype = self.name2icode['lf.cust1.s'] 631 | elif opc2 & 0xf0 == 0xe0: 632 | insn.itype = self.name2icode['lf.cust1.d'] 633 | 634 | # vector 635 | elif opc == 0x0a: 636 | opc2 = raw & 0xff 637 | if opc2 in self.maptbl_vec: 638 | insn.itype = self.maptbl_vec[opc2] 639 | insn.Op1.type = o_reg 640 | insn.Op1.reg = rD 641 | insn.Op2.type = o_reg 642 | insn.Op2.reg = rA 643 | insn.Op3.type = o_reg 644 | insn.Op3.reg = rB 645 | elif opc2 & 0xf0 == 0xc0: 646 | insn.itype = self.name2icode['lv.cust1'] 647 | elif opc2 & 0xf0 == 0xd0: 648 | insn.itype = self.name2icode['lv.cust2'] 649 | elif opc2 & 0xf0 == 0xe0: 650 | insn.itype = self.name2icode['lv.cust3'] 651 | elif opc2 & 0xf0 == 0xf0: 652 | insn.itype = self.name2icode['lv.cust4'] 653 | else: 654 | return 0 655 | 656 | # reserved 657 | elif opc == 0x3c: 658 | insn.itype = self.name2icode['l.cust5'] 659 | insn.Op1.type = o_reg 660 | insn.Op1.reg = rD 661 | insn.Op2.type = o_reg 662 | insn.Op2.reg = rA 663 | insn.Op3.type = o_reg 664 | insn.Op3.reg = rB 665 | insn.Op4.type = o_imm 666 | insn.Op4.value = raw >> 5 & 0x3f # L 667 | insn.Op5.type = o_imm 668 | insn.Op5.value = raw & 0x1f # K 669 | elif opc == 0x3d: 670 | insn.itype = self.name2icode['l.cust6'] 671 | elif opc == 0x3e: 672 | insn.itype = self.name2icode['l.cust7'] 673 | elif opc == 0x3f: 674 | insn.itype = self.name2icode['l.cust8'] 675 | 676 | else: 677 | return 0 678 | return insn.size 679 | 680 | # ---------------------------------------------------------------------- 681 | # should be faster than using decode_insn 682 | def decode_rD(self, raw): 683 | opc = (raw >> 26) & 0x3f 684 | rD = (raw >> 21) & 0x1f 685 | # arith 686 | if opc == 0x38: 687 | opc2 = raw & 0xf 688 | if opc2 == 7 or opc2 == 0xc: # l.muld, l.muldu 689 | return DECODE_RD_NONE 690 | return rD 691 | # load, arith imm16 692 | if opc >= 0x1a and opc <= 0x2e: 693 | if opc >= 0x1c and opc < 0x20: # l.cust* 694 | return DECODE_RD_CUST 695 | return rD 696 | if opc in [0x00, 0x11, 0x09]: # l.j, l.jr, l.rfe 697 | return DECODE_RD_JUMP 698 | if opc == 0x01 or opc == 0x12: # l.jal, l.jalr 699 | return DECODE_RD_CALL 700 | if opc == 0x02 or opc == 0x06: # l.adrp, l.movhi, l.macrc 701 | return rD 702 | if opc == 0x32: # float 703 | if raw & 0xff >= 0xd0: # lf.cust1.* 704 | return DECODE_RD_CUST 705 | if raw & 0x08: # lf.sf* 706 | return DECODE_RD_NONE 707 | return rD 708 | if opc == 0x0a: # vector 709 | if raw & 0xff >= 0xc0: # lv.cust* 710 | return DECODE_RD_CUST 711 | return rD 712 | return DECODE_RD_NONE 713 | 714 | # ---------------------------------------------------------------------- 715 | def find_movhi(self, insn): 716 | reg = insn.Op2.reg 717 | ea = insn.ea 718 | if reg == 0: 719 | return 720 | preserved = CALLEE_SAVED_MASK >> reg & 1 721 | for i in range(0, FIND_MOVHI_RANGE): 722 | if not get_flags(ea) & FF_FLOW: 723 | return False 724 | ea -= 4 725 | prev = get_wide_dword(ea) 726 | rD = self.decode_rD(prev) 727 | if rD == DECODE_RD_JUMP: 728 | break 729 | if rD == DECODE_RD_CALL and not preserved: 730 | break 731 | if rD != reg: 732 | continue 733 | if prev & 0xfc010000 != 0x18000000: # l.movhi 734 | break 735 | 736 | value = (prev & 0xffff) << 16 737 | if insn.itype == self.itype_ori: 738 | value |= insn.Op3.value 739 | else: 740 | value += insn.Op3.value 741 | insn.Op3.value = value & 0xffffffff 742 | insn.auxpref = AUX_LO 743 | return 744 | 745 | # ---------------------------------------------------------------------- 746 | def handle_operand(self, insn, op, dref_flag, no_delay): 747 | if op.type == o_near: 748 | if insn.get_canon_feature() & CF_CALL: 749 | insn.add_cref(op.addr, 0, fl_CN) 750 | elif no_delay != 0: 751 | insn.add_cref(op.addr, 0, fl_JN) 752 | 753 | def notify_emu(self, insn): 754 | Feature = insn.get_canon_feature() 755 | nd = ida_segregs.get_sreg(insn.ea, self.ireg_ND) 756 | 757 | if Feature & CF_USE1: 758 | self.handle_operand(insn, insn.Op1, dr_R, nd) 759 | if Feature & CF_CHG1: 760 | self.handle_operand(insn, insn.Op1, dr_W, nd) 761 | if Feature & CF_USE2: 762 | self.handle_operand(insn, insn.Op2, dr_R, nd) 763 | if Feature & CF_USE3: 764 | self.handle_operand(insn, insn.Op3, dr_R, nd) 765 | if Feature & CF_JUMP: 766 | remember_problem(PR_JUMP, insn.ea) 767 | 768 | # delay slot (CPUCFGR[ND] == 0) 769 | if nd == 0: 770 | # try: 771 | if get_flags(insn.ea) & FF_FLOW != 0: 772 | prev = get_wide_dword(insn.ea - 4) 773 | prev_opc = prev >> 26 & 0x3f 774 | if prev_opc in [0, 3, 4]: # l.j, l.bnf, l.bf 775 | addr = (insn.ea - 4 + SIGNEXT(prev, 26) * 4) & 0xffffffff 776 | insn.add_cref(addr, 0, fl_JN) 777 | # except: 778 | else: 779 | prev_opc = 0x40 780 | 781 | cur = get_wide_dword(insn.ea) 782 | flow = cur >> 26 & 0x3f != 0x09 # l.rfe 783 | if flow: 784 | flow = not prev_opc in [0, 0x11] # l.j, l.jr 785 | # no delay slot 786 | else: 787 | flow = Feature & CF_STOP == 0 788 | if flow: 789 | add_cref(insn.ea, insn.ea + insn.size, fl_F) 790 | 791 | return True 792 | 793 | # ---------------------------------------------------------------------- 794 | def notify_out_operand(self, ctx, op): 795 | optype = op.type 796 | 797 | if optype == o_reg: 798 | ctx.out_register(self.reg_names[op.reg]) 799 | elif optype == o_imm: 800 | if ctx.insn.auxpref & AUX_LO: 801 | ctx.out_line('lo', COLOR_KEYWORD) 802 | ctx.out_symbol('(') 803 | ctx.out_value(op, OOFW_32) 804 | ctx.out_symbol(')') 805 | else: 806 | # TODO: OOFW_IMM uses op.dtype 807 | ctx.out_value(op, OOFW_32 | OOF_SIGNED) 808 | elif optype == o_near: 809 | r = ctx.out_name_expr(op, op.addr, BADADDR) 810 | if not r: 811 | ctx.out_tagon(COLOR_ERROR) 812 | ctx.out_long(op.addr, 16) 813 | ctx.out_tagoff(COLOR_ERROR) 814 | remember_problem(PR_NONAME, ctx.insn.ea) 815 | elif optype == o_displ: 816 | # 16-bit index is signed 817 | ctx.out_value(op, OOF_ADDR | OOFW_16 | OOF_SIGNED) 818 | ctx.out_symbol('(') 819 | ctx.out_register(self.reg_names[op.reg]) 820 | ctx.out_symbol(')') 821 | else: 822 | return False 823 | 824 | return True 825 | 826 | # ---------------------------------------------------------------------- 827 | def notify_newfile(self, ctx): 828 | """A new file is loaded (already)""" 829 | for n in range(ida_segment.get_segm_qty()): 830 | seg = ida_segment.getnseg(n) 831 | if seg: 832 | ida_segregs.set_default_sreg_value(seg, self.ireg_ND, DEFAULT_ND) 833 | return 0 834 | 835 | # ---------------------------------------------------------------------- 836 | def notify_out_assumes(self, ctx): 837 | """function to produce assume directives""" 838 | # or idc.get_sreg(ctx.insn.ea, "ND") 839 | seg = ida_segment.getseg(ctx.bin_ea) 840 | if not seg: 841 | return 0 842 | 843 | nd = ida_segregs.get_sreg(ctx.bin_ea, self.ireg_ND) 844 | if ctx.bin_ea == seg.start_ea: 845 | prev_nd = ~nd 846 | else: 847 | prev_nd = ida_segregs.get_sreg(ctx.bin_ea - 1, self.ireg_ND) 848 | 849 | if nd != prev_nd: 850 | ctx.out_line("# ND = " + str(nd), COLOR_REGCMT) 851 | ctx.flush_outbuf() 852 | return 1 853 | 854 | # ---------------------------------------------------------------------- 855 | def out_mnem(self, ctx): 856 | ctx.out_mnem(16, "") 857 | return 1 858 | 859 | # ---------------------------------------------------------------------- 860 | def notify_out_insn(self, ctx): 861 | ctx.out_mnemonic() 862 | 863 | if ctx.insn.Op1.type != o_void: 864 | ctx.out_one_operand(0) 865 | for i in range(1, 5): 866 | if ctx.insn[i].type == o_void: 867 | break 868 | ctx.out_symbol(',') 869 | ctx.out_char(' ') 870 | ctx.out_one_operand(i) 871 | 872 | ctx.set_gen_cmt() 873 | ctx.flush_outbuf() 874 | return True 875 | 876 | # ---------------------------------------------------------------------- 877 | 878 | # Array of instructions 879 | instruc = [ 880 | {'name': '', 'feature': 0, 'cmt': 'bad opcode'}, 881 | 882 | # opcode 0x00..0x05 883 | {'name': 'l.j', 'feature': CF_USE1 | CF_JUMP | CF_STOP, 'cmt': 'Jump'}, 884 | {'name': 'l.jal', 'feature': CF_USE1 | CF_CALL, 'cmt': 'Jump and Link'}, 885 | {'name': 'l.adrp', 'feature': CF_CHG1 | CF_USE2, 'cmt': 'Compute Instruction Relative Address'}, 886 | {'name': 'l.bnf', 'feature': CF_USE1 | CF_JUMP, 'cmt': 'Branch if No Flag'}, 887 | {'name': 'l.bf', 'feature': CF_USE1 | CF_JUMP, 'cmt': 'Branch if Flag'}, 888 | {'name': 'l.nop', 'feature': CF_USE1, 'cmt': 'No Operation'}, 889 | # opcode 0x06 890 | {'name': 'l.movhi', 'feature': CF_CHG1 | CF_USE2, 'cmt': 'Move Immediate High'}, 891 | {'name': 'l.macrc', 'feature': CF_CHG1, 'cmt': 'MAC Read and Clear'}, 892 | # opcode 0x08 893 | {'name': 'l.sys', 'feature': CF_USE1, 'cmt': 'System Call'}, 894 | {'name': 'l.trap', 'feature': CF_USE1, 'cmt': 'Trap'}, 895 | {'name': 'l.msync', 'feature': 0, 'cmt': 'Memory Synchronization'}, 896 | {'name': 'l.psync', 'feature': 0, 'cmt': 'Pipeline Synchronization'}, 897 | {'name': 'l.csync', 'feature': 0, 'cmt': 'Context Synchronization'}, 898 | # opcode 0x09 899 | {'name': 'l.rfe', 'feature': CF_STOP, 'cmt': 'Return From Exception'}, 900 | # opcode 0x0a 901 | {'name': 'lv.cust1', 'feature': 0, 'cmt': 'Reserved for Custom Instructions'}, 902 | {'name': 'lv.cust2', 'feature': 0, 'cmt': 'Reserved for Custom Instructions'}, 903 | {'name': 'lv.cust3', 'feature': 0, 'cmt': 'Reserved for Custom Instructions'}, 904 | {'name': 'lv.cust4', 'feature': 0, 'cmt': 'Reserved for Custom Instructions'}, 905 | # lv.{all,any}_{cc}.{b,h} 906 | {'name': 'lv.add.b', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Byte Elements Add Signed'}, 907 | {'name': 'lv.add.h', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Half-Word Elements Add Signed'}, 908 | {'name': 'lv.adds.b', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Byte Elements Add Signed Saturated'}, 909 | {'name': 'lv.adds.h', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Half-Word Elements Add Signed Saturated'}, 910 | {'name': 'lv.addu.b', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Byte Elements Add Unsigned'}, 911 | {'name': 'lv.addu.h', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Half-Word Elements Add Unsigned'}, 912 | {'name': 'lv.addus.b', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Byte Elements Add Unsigned Saturated'}, 913 | {'name': 'lv.addus.h', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Half-Word Elements Add Unsigned Saturated'}, 914 | {'name': 'lv.and', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector And'}, 915 | {'name': 'lv.avg.b', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Byte Elements Average'}, 916 | {'name': 'lv.avg.h', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Half-Word Elements Average'}, 917 | # lv.cmp_{cc}.{b,h} 918 | {'name': 'lv.madds.h', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Half-Word Elements Multiply Add Signed Saturated'}, 919 | {'name': 'lv.max.b', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Byte Elements Maximum'}, 920 | {'name': 'lv.max.h', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Half-Word Elements Maximum'}, 921 | {'name': 'lv.merge.b', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Byte Elements Merge'}, 922 | {'name': 'lv.merge.h', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Half-Word Elements Merge'}, 923 | {'name': 'lv.min.b', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Byte Elements Minimum'}, 924 | {'name': 'lv.min.h', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Half-Word Elements Minimum'}, 925 | {'name': 'lv.msubs.h', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Half-Word Elements Multiply Subtract Signed Saturated'}, 926 | {'name': 'lv.muls.h', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Half-Word Elements Multiply Signed Saturated'}, 927 | {'name': 'lv.nand', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Not And'}, 928 | {'name': 'lv.nor', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Not Or'}, 929 | {'name': 'lv.or', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Or'}, 930 | {'name': 'lv.pack.b', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Byte Elements Pack'}, 931 | {'name': 'lv.pack.h', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Half-word Elements Pack'}, 932 | {'name': 'lv.packs.b', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Byte Elements Pack Signed Saturated'}, 933 | {'name': 'lv.packs.h', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Half-word Elements Pack Signed Saturated'}, 934 | {'name': 'lv.packus.b', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Byte Elements Pack Unsigned Saturated'}, 935 | {'name': 'lv.packus.h', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Half-word Elements Pack Unsigned Saturated'}, 936 | {'name': 'lv.perm.n', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Nibble Elements Permute'}, 937 | {'name': 'lv.rl.b', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Byte Elements Rotate Left'}, 938 | {'name': 'lv.rl.h', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Half-Word Elements Rotate Left'}, 939 | {'name': 'lv.sll.b', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Byte Elements Shift Left Logical'}, 940 | {'name': 'lv.sll.h', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Half-Word Elements Shift Left Logical'}, 941 | {'name': 'lv.sll', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Shift Left Logical'}, 942 | {'name': 'lv.srl.b', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Byte Elements Shift Right Logical'}, 943 | {'name': 'lv.srl.h', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Half-Word Elements Shift Right Logical'}, 944 | {'name': 'lv.sra.b', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Byte Elements Shift Right Arithmetic'}, 945 | {'name': 'lv.sra.h', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Half-Word Elements Shift Right Arithmetic'}, 946 | {'name': 'lv.srl', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Shift Right Logical'}, 947 | {'name': 'lv.sub.b', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Byte Elements Subtract Signed'}, 948 | {'name': 'lv.sub.h', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Half-Word Elements Subtract Signed'}, 949 | {'name': 'lv.subs.b', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Byte Elements Subtract Signed Saturated'}, 950 | {'name': 'lv.subs.h', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Half-Word Elements Subtract Signed Saturated'}, 951 | {'name': 'lv.subu.b', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Byte Elements Subtract Unsigned'}, 952 | {'name': 'lv.subu.h', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Half-Word Elements Subtract Unsigned'}, 953 | {'name': 'lv.subus.b', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Byte Elements Subtract Unsigned Saturated'}, 954 | {'name': 'lv.subus.h', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Half-Word Elements Subtract Unsigned Saturated'}, 955 | {'name': 'lv.unpack.b', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Byte Elements Unpack'}, 956 | {'name': 'lv.unpack.h', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Half-Word Elements Unpack'}, 957 | {'name': 'lv.xor', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Vector Exclusive Or'}, 958 | 959 | # opcode 0x11..0x13 960 | {'name': 'l.jr', 'feature': CF_USE1 | CF_JUMP | CF_STOP, 'cmt': 'Jump Register'}, 961 | {'name': 'l.jalr', 'feature': CF_USE1 | CF_CALL, 'cmt': 'Jump and Link Register'}, 962 | {'name': 'l.maci', 'feature': CF_USE1 | CF_USE2, 'cmt': 'Multiply Immediate Signed and Accumulate'}, 963 | 964 | # opcode 0x1a..0x26 965 | {'name': 'l.lf', 'feature': CF_CHG1 | CF_USE2, 'cmt': 'Load Single Float Word with NaN Boxing'}, 966 | {'name': 'l.lwa', 'feature': CF_CHG1 | CF_USE2, 'cmt': 'Load Single Word Atomic'}, 967 | {'name': 'l.cust1', 'feature': 0, 'cmt': 'Reserved for Custom Instructions'}, 968 | {'name': 'l.cust2', 'feature': 0, 'cmt': 'Reserved for Custom Instructions'}, 969 | {'name': 'l.cust3', 'feature': 0, 'cmt': 'Reserved for Custom Instructions'}, 970 | {'name': 'l.cust4', 'feature': 0, 'cmt': 'Reserved for Custom Instructions'}, 971 | {'name': 'l.ld', 'feature': CF_CHG1 | CF_USE2, 'cmt': 'Load Double Word'}, 972 | {'name': 'l.lwz', 'feature': CF_CHG1 | CF_USE2, 'cmt': 'Load Single Word and Extend with Zero'}, 973 | {'name': 'l.lws', 'feature': CF_CHG1 | CF_USE2, 'cmt': 'Load Single Word and Extend with Sign'}, 974 | {'name': 'l.lbz', 'feature': CF_CHG1 | CF_USE2, 'cmt': 'Load Byte and Extend with Zero'}, 975 | {'name': 'l.lbs', 'feature': CF_CHG1 | CF_USE2, 'cmt': 'Load Byte and Extend with Sign'}, 976 | {'name': 'l.lhz', 'feature': CF_CHG1 | CF_USE2, 'cmt': 'Load Half Word and Extend with Zero'}, 977 | {'name': 'l.lhs', 'feature': CF_CHG1 | CF_USE2, 'cmt': 'Load Half Word and Extend with Sign'}, 978 | 979 | # opcode 0x27..0x2d 980 | {'name': 'l.addi', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Add Immediate Signed'}, 981 | {'name': 'l.addic', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Add Immediate Signed and Carry'}, 982 | {'name': 'l.andi', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'And with Immediate Half Word'}, 983 | {'name': 'l.ori', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Or with Immediate Half Word'}, 984 | {'name': 'l.xori', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Exclusive Or with Immediate Half Word'}, 985 | {'name': 'l.muli', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Multiply Immediate Signed'}, 986 | {'name': 'l.mfspr', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Move From Special-Purpose Register'}, 987 | # opcode 0x2e 988 | {'name': 'l.slli', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Shift Left Logical with Immediate'}, 989 | {'name': 'l.srli', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Shift Right Logical with Immediate'}, 990 | {'name': 'l.srai', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Shift Right Logical with Immediate'}, 991 | {'name': 'l.rori', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Rotate Right with Immediate'}, 992 | # opcode 0x2f 993 | # l.sf{cc}i 994 | # opcode 0x30 995 | {'name': 'l.mtspr', 'feature': CF_USE1 | CF_USE2 | CF_USE3, 'cmt': 'Move To Special-Purpose Register'}, 996 | # opcode 0x31 997 | {'name': 'l.mac', 'feature': CF_USE1 | CF_USE2, 'cmt': 'Multiply Signed and Accumulate'}, 998 | {'name': 'l.msb', 'feature': CF_USE1 | CF_USE2, 'cmt': 'Multiply Signed and Subtract'}, 999 | {'name': 'l.macu', 'feature': CF_USE1 | CF_USE2, 'cmt': 'Multiply Unsigned and Accumulate'}, 1000 | {'name': 'l.msbu', 'feature': CF_USE1 | CF_USE2, 'cmt': 'Multiply Unsigned and Subtract'}, 1001 | 1002 | # opcode 0x32 1003 | {'name': 'lf.add.s', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Add Floating-Point Single-Precision'}, 1004 | {'name': 'lf.sub.s', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Subtract Floating-Point Single-Precision'}, 1005 | {'name': 'lf.mul.s', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Multiply Floating-Point Single-Precision'}, 1006 | {'name': 'lf.div.s', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Divide Floating-Point Single-Precision'}, 1007 | {'name': 'lf.itof.s', 'feature': CF_CHG1 | CF_USE2, 'cmt': 'Integer To Floating-Point Single-Precision'}, 1008 | {'name': 'lf.ftoi.s', 'feature': CF_CHG1 | CF_USE2, 'cmt': 'Floating-Point Single-Precision To Integer'}, 1009 | {'name': 'lf.rem.s', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Remainder Floating-Point Single-Precision'}, 1010 | {'name': 'lf.madd.s', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Multiply and Add Floating-Point Single-Precision'}, 1011 | # lf.sf{cc}.s 1012 | {'name': 'lf.add.d', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Add Floating-Point Double-Precision'}, 1013 | {'name': 'lf.sub.d', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Subtract Floating-Point Double-Precision'}, 1014 | {'name': 'lf.mul.d', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Multiply Floating-Point Double-Precision'}, 1015 | {'name': 'lf.div.d', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Divide Floating-Point Double-Precision'}, 1016 | {'name': 'lf.itof.d', 'feature': CF_CHG1 | CF_USE2, 'cmt': 'Integer To Floating-Point Double-Precision'}, 1017 | {'name': 'lf.ftoi.d', 'feature': CF_CHG1 | CF_USE2, 'cmt': 'Floating-Point Double-Precision To Integer'}, 1018 | {'name': 'lf.rem.d', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Remainder Floating-Point Double-Precision'}, 1019 | {'name': 'lf.madd.d', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Multiply and Add Floating-Point Double-Precision'}, 1020 | # lf.sf{cc}.d 1021 | # lf.sfu{cc}.s 1022 | {'name': 'lf.stod.d', 'feature': CF_CHG1 | CF_USE2, 'cmt': 'Convert Single-precision Floating-Point Number To Double-precision'}, 1023 | {'name': 'lf.dtos.d', 'feature': CF_CHG1 | CF_USE2, 'cmt': 'Convert Double-precision Floating-Point Number to Single-precision'}, 1024 | # lf.sfu{cc}.d 1025 | {'name': 'lf.cust1.s', 'feature': CF_USE1 | CF_USE2, 'cmt': 'Reserved for Custom Instructions'}, 1026 | {'name': 'lf.cust1.d', 'feature': CF_USE1 | CF_USE2, 'cmt': 'Reserved for Custom Instructions'}, 1027 | 1028 | # opcode 0x33..0x37 1029 | {'name': 'l.swa', 'feature': CF_USE1 | CF_USE2, 'cmt': 'Store Single Word Atomic'}, 1030 | {'name': 'l.sd', 'feature': CF_USE1 | CF_USE2, 'cmt': 'Store Double Word'}, 1031 | {'name': 'l.sw', 'feature': CF_USE1 | CF_USE2, 'cmt': 'Store Single Word'}, 1032 | {'name': 'l.sb', 'feature': CF_USE1 | CF_USE2, 'cmt': 'Store Byte'}, 1033 | {'name': 'l.sh', 'feature': CF_USE1 | CF_USE2, 'cmt': 'Store Half Word'}, 1034 | # opcode 0x38 1035 | {'name': 'l.exths', 'feature': CF_CHG1 | CF_USE2, 'cmt': 'Extend Half Word with Sign'}, 1036 | {'name': 'l.extbs', 'feature': CF_CHG1 | CF_USE2, 'cmt': 'Extend Byte with Sign'}, 1037 | {'name': 'l.exthz', 'feature': CF_CHG1 | CF_USE2, 'cmt': 'Extend Half Word with Zero'}, 1038 | {'name': 'l.extbz', 'feature': CF_CHG1 | CF_USE2, 'cmt': 'Extend Byte with Zero'}, 1039 | {'name': 'l.extws', 'feature': CF_CHG1 | CF_USE2, 'cmt': 'Extend Word with Sign'}, 1040 | {'name': 'l.extwz', 'feature': CF_CHG1 | CF_USE2, 'cmt': 'Extend Word with Zero'}, 1041 | {'name': 'l.add', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Add Signed'}, 1042 | {'name': 'l.addc', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Add Signed and Carry'}, 1043 | {'name': 'l.sub', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Subtract Signed'}, 1044 | {'name': 'l.and', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'And'}, 1045 | {'name': 'l.or', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Or'}, 1046 | {'name': 'l.xor', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Exclusive Or'}, 1047 | {'name': 'l.sll', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Shift Left Logical'}, 1048 | {'name': 'l.srl', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Shift Right Logical'}, 1049 | {'name': 'l.sra', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Shift Right Arithmetic'}, 1050 | {'name': 'l.ror', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Rotate Right'}, 1051 | {'name': 'l.cmov', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Conditional Move'}, 1052 | {'name': 'l.ff1', 'feature': CF_CHG1 | CF_USE2, 'cmt': 'Find First 1'}, 1053 | {'name': 'l.fl1', 'feature': CF_CHG1 | CF_USE2, 'cmt': 'Find Last 1'}, 1054 | {'name': 'l.mul', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Multiply Signed'}, 1055 | {'name': 'l.muld', 'feature': CF_USE1 | CF_USE2, 'cmt': 'Multiply Signed to Double'}, 1056 | {'name': 'l.div', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Divide Signed'}, 1057 | {'name': 'l.divu', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Divide Unsigned'}, 1058 | {'name': 'l.mulu', 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': 'Multiply Unsigned'}, 1059 | {'name': 'l.muldu', 'feature': CF_USE1 | CF_USE2, 'cmt': 'Multiply Unsigned to Double'}, 1060 | 1061 | # opcode 0x39 1062 | # l.sf{cc} 1063 | # opcode 0x3c..0x3f 1064 | {'name': 'l.cust5', 'feature': CF_USE1 | CF_USE2 | CF_USE3 | CF_USE4 | CF_USE5, 'cmt': 'Reserved for Custom Instructions'}, 1065 | {'name': 'l.cust6', 'feature': 0, 'cmt': 'Reserved for Custom Instructions'}, 1066 | {'name': 'l.cust7', 'feature': 0, 'cmt': 'Reserved for Custom Instructions'}, 1067 | {'name': 'l.cust8', 'feature': 0, 'cmt': 'Reserved for Custom Instructions'} 1068 | ] 1069 | 1070 | # icode of the first instruction 1071 | instruc_start = 0 1072 | 1073 | def maptbl_icode(self, tab): 1074 | for i, s in enumerate(tab): 1075 | tab[i] = self.name2icode[s] 1076 | 1077 | def mapdict_icode(self, tab): 1078 | for i, s in tab.items(): 1079 | tab[i] = self.name2icode[s] 1080 | 1081 | def init_instructions(self): 1082 | 1083 | setflag_names = [ 1084 | ['eq', 'Equal', ''], 1085 | ['ne', 'Not Equal', ''], 1086 | ['gtu', 'Greater Than', ' Unsigned'], 1087 | ['geu', 'Greater or Equal Than', ' Unsigned'], 1088 | ['ltu', 'Less Than', ' Unsigned'], 1089 | ['leu', 'Less or Equal Than', ' Unsigned'], 1090 | ['gts', 'Greater Than', ' Signed'], 1091 | ['ges', 'Greater or Equal Than', ' Signed'], 1092 | ['lts', 'Less Than', ' Signed'], 1093 | ['les', 'Less or Equal Than', ' Signed'] 1094 | ] 1095 | 1096 | # opcode 0x2f, 0x39 1097 | for x in setflag_names: 1098 | name = 'l.sf' + x[0] 1099 | cmt = 'Set Flag if ' + x[1] 1100 | self.instruc.append({'name': name, 'feature': CF_USE1 | CF_USE2, 'cmt': cmt + x[2]}) 1101 | self.instruc.append({'name': name + 'i', 'feature': CF_USE1 | CF_USE2, 'cmt': cmt + ' Immediate' + x[2]}) 1102 | 1103 | vcmp_names = [ 1104 | ['eq', 'Equal'], 1105 | ['ge', 'Greater Than or Equal To'], 1106 | ['gt', 'Greater Than'], 1107 | ['le', 'Less Than or Equal To'], 1108 | ['lt', 'Less Than'], 1109 | ['ne', 'Not Equal'] 1110 | ] 1111 | 1112 | # opcode 0x0a 1113 | for n1, c1 in [['all_', 'All '], ['any_', 'Any '], ['cmp_', 'Compare ']]: 1114 | for x in vcmp_names: 1115 | for n2, c2 in [['.b', 'Byte'], ['.h', 'Half-Word']]: 1116 | name = 'lv.' + n1 + x[0] + n2 1117 | cmt = 'Vector ' + c2 + ' Elements ' + c1 + x[1] 1118 | self.instruc.append({'name': name, 'feature': CF_CHG1 | CF_USE2 | CF_USE3, 'cmt': cmt}) 1119 | 1120 | fcmp_names = [ 1121 | ['eq', 'Equal'], 1122 | ['ne', 'Not Equal'], 1123 | ['gt', 'Greater Than'], 1124 | ['ge', 'Greater Than or Equal'], 1125 | ['lt', 'Less Than'], 1126 | ['le', 'Less Than or Equal'], 1127 | ['ueq', 'Unordered or Equal'], 1128 | ['une', 'Unordered or Not Equal'], 1129 | ['ugt', 'Unordered or Greater Than'], 1130 | ['uge', 'Unordered or Greater Than or Equal'], 1131 | ['ult', 'Unordered or Less Than'], 1132 | ['ule', 'Unordered or Less Than or Equal'], 1133 | ['un', 'Unordered'] 1134 | ] 1135 | 1136 | # opcode 0x32 1137 | for n, c in [['.s', 'Single'], ['.d', 'Double']]: 1138 | for x in fcmp_names: 1139 | name = 'lf.sf' + x[0] + n 1140 | cmt = 'Set Flag if ' + x[1] + ' Floating-Point ' + c + '-Precision' 1141 | self.instruc.append({'name': name, 'feature': CF_USE1 | CF_USE2, 'cmt': cmt}) 1142 | 1143 | self.name2icode = {} 1144 | for i, x in enumerate(self.instruc): 1145 | self.name2icode[x['name']] = i 1146 | 1147 | # icode of the last instruction + 1 1148 | self.instruc_end = len(self.instruc) 1149 | 1150 | self.itype_movhi = self.name2icode['l.movhi'] 1151 | self.itype_ori = self.name2icode['l.ori'] 1152 | 1153 | self.maptbl_shift_imm = list() 1154 | for s in self.maptbl_shift: 1155 | self.maptbl_shift_imm.append(self.name2icode[s + 'i']) 1156 | 1157 | self.maptbl_setflag_imm = dict() 1158 | for i, s in self.maptbl_setflag.items(): 1159 | self.maptbl_setflag_imm[i] = self.name2icode[s + 'i'] 1160 | 1161 | self.maptbl_icode(self.maptbl_jump) 1162 | self.maptbl_icode(self.maptbl_shift) 1163 | self.maptbl_icode(self.maptbl_load) 1164 | self.maptbl_icode(self.maptbl_store) 1165 | self.maptbl_icode(self.maptbl_27) 1166 | self.maptbl_icode(self.maptbl_38) 1167 | self.mapdict_icode(self.maptbl_setflag) 1168 | self.mapdict_icode(self.maptbl_float) 1169 | self.mapdict_icode(self.maptbl_vec) 1170 | 1171 | # ---------------------------------------------------------------------- 1172 | 1173 | # Registers definition 1174 | reg_names = [ 1175 | # General purpose registers 1176 | # r0: fixed to zero 1177 | # r1: SP (Stack pointer) 1178 | # r2: FP (Frame pointer) 1179 | # r3..r8: function args 1180 | # r9: LR (Link Register) 1181 | # r10: TLS (Thread Local Storage) 1182 | # r11: return value 1183 | # r12: return value high 1184 | # r13..r31: odd = temp, even = callee-saved 1185 | "r0", "sp", "r2", "r3", "r4", "r5", "r6", "r7", 1186 | "r8", "lr", "r10", "r11", "r12", "r13", "r14", "r15", 1187 | "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", 1188 | "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", 1189 | 1190 | # Fake segment registers 1191 | "CS", "ND", "DS" 1192 | ] 1193 | 1194 | def init_registers(self): 1195 | self.ireg_ND = self.reg_names.index("ND") 1196 | 1197 | # number of CS register 1198 | self.reg_code_sreg = self.reg_names.index("CS") 1199 | 1200 | # number of DS register 1201 | self.reg_data_sreg = self.reg_names.index("DS") 1202 | 1203 | # Segment register information (use virtual CS and DS registers if your 1204 | # processor doesn't have segment registers): 1205 | self.reg_first_sreg = self.reg_code_sreg 1206 | self.reg_last_sreg = self.reg_data_sreg 1207 | 1208 | # ---------------------------------------------------------------------- 1209 | def __init__(self): 1210 | processor_t.__init__(self) 1211 | self.init_instructions() 1212 | self.init_registers() 1213 | 1214 | # ---------------------------------------------------------------------- 1215 | # Every processor module script must provide this function. 1216 | # It should return a new instance of a class derived from processor_t 1217 | def PROCESSOR_ENTRY(): 1218 | return or1k_processor_t() 1219 | --------------------------------------------------------------------------------