| File: | arch/amd64/amd64/db_disasm.c |
| Warning: | line 957, column 6 Branch condition evaluates to a garbage value |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* $OpenBSD: db_disasm.c,v 1.24 2023/04/22 18:26:17 guenther Exp $ */ | |||
| 2 | /* $NetBSD: db_disasm.c,v 1.11 1996/05/03 19:41:58 christos Exp $ */ | |||
| 3 | ||||
| 4 | /* | |||
| 5 | * Mach Operating System | |||
| 6 | * Copyright (c) 1991,1990 Carnegie Mellon University | |||
| 7 | * All Rights Reserved. | |||
| 8 | * | |||
| 9 | * Permission to use, copy, modify and distribute this software and its | |||
| 10 | * documentation is hereby granted, provided that both the copyright | |||
| 11 | * notice and this permission notice appear in all copies of the | |||
| 12 | * software, derivative works or modified versions, and any portions | |||
| 13 | * thereof, and that both notices appear in supporting documentation. | |||
| 14 | * | |||
| 15 | * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" | |||
| 16 | * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR | |||
| 17 | * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. | |||
| 18 | * | |||
| 19 | * Carnegie Mellon requests users of this software to return to | |||
| 20 | * | |||
| 21 | * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU | |||
| 22 | * School of Computer Science | |||
| 23 | * Carnegie Mellon University | |||
| 24 | * Pittsburgh PA 15213-3890 | |||
| 25 | * | |||
| 26 | * any improvements or extensions that they make and grant Carnegie Mellon | |||
| 27 | * the rights to redistribute these changes. | |||
| 28 | * | |||
| 29 | * Id: db_disasm.c,v 2.6 92/01/03 20:05:00 dbg (CMU) | |||
| 30 | */ | |||
| 31 | ||||
| 32 | /* | |||
| 33 | * Instruction disassembler. | |||
| 34 | */ | |||
| 35 | #include <sys/param.h> | |||
| 36 | #include <sys/systm.h> | |||
| 37 | #include <machine/db_machdep.h> | |||
| 38 | ||||
| 39 | #include <ddb/db_access.h> | |||
| 40 | #include <ddb/db_sym.h> | |||
| 41 | #include <ddb/db_output.h> | |||
| 42 | ||||
| 43 | /* | |||
| 44 | * Size attributes | |||
| 45 | */ | |||
| 46 | #define BYTE0 0 | |||
| 47 | #define WORD1 1 | |||
| 48 | #define LONG2 2 | |||
| 49 | #define QUAD3 3 | |||
| 50 | #define SNGL4 4 | |||
| 51 | #define DBLR5 5 | |||
| 52 | #define EXTR6 6 | |||
| 53 | #define SDEP7 7 | |||
| 54 | #define NONE8 8 | |||
| 55 | #define RDEP9 9 | |||
| 56 | ||||
| 57 | /* | |||
| 58 | * Addressing modes | |||
| 59 | */ | |||
| 60 | #define E1 1 /* general effective address */ | |||
| 61 | #define Eind2 2 /* indirect address (jump, call) */ | |||
| 62 | #define Ew3 3 /* address, word size */ | |||
| 63 | #define Eb4 4 /* address, byte size */ | |||
| 64 | #define R5 5 /* register, in 'reg' field */ | |||
| 65 | #define Rw6 6 /* word register, in 'reg' field */ | |||
| 66 | #define Ri7 7 /* register in instruction */ | |||
| 67 | #define S8 8 /* segment reg, in 'reg' field */ | |||
| 68 | #define Si9 9 /* segment reg, in instruction */ | |||
| 69 | #define A10 10 /* accumulator */ | |||
| 70 | #define BX11 11 /* (bx) */ | |||
| 71 | #define CL12 12 /* cl, for shifts */ | |||
| 72 | #define DX13 13 /* dx, for IO */ | |||
| 73 | #define SI14 14 /* si */ | |||
| 74 | #define DI15 15 /* di */ | |||
| 75 | #define CR16 16 /* control register */ | |||
| 76 | #define DR17 17 /* debug register */ | |||
| 77 | #define TR18 18 /* test register */ | |||
| 78 | #define I19 19 /* immediate, unsigned */ | |||
| 79 | #define Is20 20 /* immediate, signed */ | |||
| 80 | #define Ib21 21 /* byte immediate, unsigned */ | |||
| 81 | #define Ibs22 22 /* byte immediate, signed */ | |||
| 82 | #define Iw23 23 /* word immediate, unsigned */ | |||
| 83 | #define Iq24 24 /* quad immediate, unsigned */ | |||
| 84 | #define O25 25 /* direct address */ | |||
| 85 | #define Db26 26 /* byte displacement from EIP */ | |||
| 86 | #define Dl27 27 /* long displacement from EIP */ | |||
| 87 | #define o128 28 /* constant 1 */ | |||
| 88 | #define o329 29 /* constant 3 */ | |||
| 89 | #define OS30 30 /* immediate offset/segment */ | |||
| 90 | #define ST31 31 /* FP stack top */ | |||
| 91 | #define STI32 32 /* FP stack */ | |||
| 92 | #define X33 33 /* extended FP op */ | |||
| 93 | #define XA34 34 /* for 'fstcw %ax' */ | |||
| 94 | #define Ril36 36 /* long register in instruction */ | |||
| 95 | #define Iba37 37 /* byte immediate, don't print if 0xa */ | |||
| 96 | #define MEx38 38 /* memory, or an extension op */ | |||
| 97 | ||||
| 98 | struct inst { | |||
| 99 | char * i_name; /* name */ | |||
| 100 | short i_has_modrm; /* has regmodrm byte */ | |||
| 101 | short i_size; /* operand size */ | |||
| 102 | int i_mode; /* addressing modes */ | |||
| 103 | void * i_extra; /* pointer to extra opcode table */ | |||
| 104 | }; | |||
| 105 | ||||
| 106 | #define op1(x)(x) (x) | |||
| 107 | #define op2(x,y)((x)|((y)<<8)) ((x)|((y)<<8)) | |||
| 108 | #define op3(x,y,z)((x)|((y)<<8)|((z)<<16)) ((x)|((y)<<8)|((z)<<16)) | |||
| 109 | ||||
| 110 | struct finst { | |||
| 111 | char * f_name; /* name for memory instruction */ | |||
| 112 | int f_size; /* size for memory instruction */ | |||
| 113 | int f_rrmode; /* mode for rr instruction */ | |||
| 114 | void * f_rrname; /* name for rr instruction | |||
| 115 | (or pointer to table) */ | |||
| 116 | }; | |||
| 117 | ||||
| 118 | char * db_Grp6[] = { | |||
| 119 | "sldt", "str", "lldt", "ltr", | |||
| 120 | "verr", "verw", "", "" | |||
| 121 | }; | |||
| 122 | ||||
| 123 | struct inst db_Grp7[] = { | |||
| 124 | { "sgdt", 0, NONE8, op2(MEx,5)((38)|((5)<<8)), "\0vmcall\0vmlaunch\0vmresume\0vmxoff"}, | |||
| 125 | { "sidt", 0, NONE8, op2(MEx,4)((38)|((4)<<8)), "monitor\0mwait\0clac\0stac"}, | |||
| 126 | { "lgdt", 0, NONE8, op2(MEx,7)((38)|((7)<<8)), "xgetbv\0xsetbv\0\0\0vmfunc\0xend\0xtest" }, | |||
| 127 | { "lidt", 0, NONE8, op1(E)(1), 0 }, | |||
| 128 | { "smsw", 0, NONE8, op1(E)(1), 0 }, | |||
| 129 | { "", 0, NONE8, 0, 0 }, | |||
| 130 | { "lmsw", 0, NONE8, op1(E)(1), 0 }, | |||
| 131 | { "invlpg", 0, NONE8, op2(MEx,2)((38)|((2)<<8)), "swapgs\0rdtscp" }, | |||
| 132 | }; | |||
| 133 | ||||
| 134 | char * db_Grp8[] = { | |||
| 135 | "", "", "", "", | |||
| 136 | "bt", "bts", "btr", "btc" | |||
| 137 | }; | |||
| 138 | ||||
| 139 | struct inst db_Grp9[] = { | |||
| 140 | { "fxsave", 0, NONE8, op2(MEx,1)((38)|((1)<<8)), "rdfsbase" }, | |||
| 141 | { "fxrstor", 0, NONE8, op2(MEx,1)((38)|((1)<<8)), "rdgsbase" }, | |||
| 142 | { "ldmxcsr", 0, NONE8, op2(MEx,1)((38)|((1)<<8)), "wrfsbase" }, | |||
| 143 | { "stmxcsr", 0, NONE8, op2(MEx,1)((38)|((1)<<8)), "wrgsbase" }, | |||
| 144 | { "xsave", 0, NONE8, op1(E)(1), 0 }, | |||
| 145 | { "xrstor", 0, NONE8, op2(MEx,1)((38)|((1)<<8)), "lfence" }, | |||
| 146 | { "xsaveopt", 0, NONE8, op2(MEx,1)((38)|((1)<<8)), "mfence" }, | |||
| 147 | { "clflush", 0, NONE8, op2(MEx,1)((38)|((1)<<8)), "sfence" }, | |||
| 148 | }; | |||
| 149 | ||||
| 150 | char * db_GrpA[] = { | |||
| 151 | "", "cmpxchg8b", "", "xrstors", | |||
| 152 | "xsavec", "xsaves", "rdrand", "rdseed" | |||
| 153 | }; | |||
| 154 | ||||
| 155 | char * db_GrpB[] = { | |||
| 156 | "xstore-rng", "xcrypt-ecb", "xcrypt-cbc", "xcrypt-ctr", | |||
| 157 | "xcrypt-cfb", "xcrypt-ofb", "", "" | |||
| 158 | }; | |||
| 159 | ||||
| 160 | char * db_GrpC[] = { | |||
| 161 | "montmul", "xsha1", "xsha256", "", | |||
| 162 | "", "", "", "" | |||
| 163 | }; | |||
| 164 | ||||
| 165 | struct inst db_inst_0f0x[] = { | |||
| 166 | /*00*/ { NULL((void *)0), 1, NONE8, op1(Ew)(3), db_Grp6 }, | |||
| 167 | /*01*/ { "", 1, RDEP9, 0, db_Grp7 }, | |||
| 168 | /*02*/ { "lar", 1, LONG2, op2(E,R)((1)|((5)<<8)), 0 }, | |||
| 169 | /*03*/ { "lsl", 1, LONG2, op2(E,R)((1)|((5)<<8)), 0 }, | |||
| 170 | /*04*/ { "", 0, NONE8, 0, 0 }, | |||
| 171 | /*05*/ { "", 0, NONE8, 0, 0 }, | |||
| 172 | /*06*/ { "clts", 0, NONE8, 0, 0 }, | |||
| 173 | /*07*/ { "", 0, NONE8, 0, 0 }, | |||
| 174 | ||||
| 175 | /*08*/ { "invd", 0, NONE8, 0, 0 }, | |||
| 176 | /*09*/ { "wbinvd",0, NONE8, 0, 0 }, | |||
| 177 | /*0a*/ { "", 0, NONE8, 0, 0 }, | |||
| 178 | /*0b*/ { "", 0, NONE8, 0, 0 }, | |||
| 179 | /*0c*/ { "", 0, NONE8, 0, 0 }, | |||
| 180 | /*0d*/ { "", 0, NONE8, 0, 0 }, | |||
| 181 | /*0e*/ { "", 0, NONE8, 0, 0 }, | |||
| 182 | /*0f*/ { "", 0, NONE8, 0, 0 }, | |||
| 183 | }; | |||
| 184 | ||||
| 185 | struct inst db_inst_0f2x[] = { | |||
| 186 | /*20*/ { "mov", 1, LONG2, op2(CR,E)((16)|((1)<<8)), 0 }, /* use E for reg */ | |||
| 187 | /*21*/ { "mov", 1, LONG2, op2(DR,E)((17)|((1)<<8)), 0 }, /* since mod == 11 */ | |||
| 188 | /*22*/ { "mov", 1, LONG2, op2(E,CR)((1)|((16)<<8)), 0 }, | |||
| 189 | /*23*/ { "mov", 1, LONG2, op2(E,DR)((1)|((17)<<8)), 0 }, | |||
| 190 | /*24*/ { "mov", 1, LONG2, op2(TR,E)((18)|((1)<<8)), 0 }, | |||
| 191 | /*25*/ { "", 0, NONE8, 0, 0 }, | |||
| 192 | /*26*/ { "mov", 1, LONG2, op2(E,TR)((1)|((18)<<8)), 0 }, | |||
| 193 | /*27*/ { "", 0, NONE8, 0, 0 }, | |||
| 194 | ||||
| 195 | /*28*/ { "", 0, NONE8, 0, 0 }, | |||
| 196 | /*29*/ { "", 0, NONE8, 0, 0 }, | |||
| 197 | /*2a*/ { "", 0, NONE8, 0, 0 }, | |||
| 198 | /*2b*/ { "", 0, NONE8, 0, 0 }, | |||
| 199 | /*2c*/ { "", 0, NONE8, 0, 0 }, | |||
| 200 | /*2d*/ { "", 0, NONE8, 0, 0 }, | |||
| 201 | /*2e*/ { "", 0, NONE8, 0, 0 }, | |||
| 202 | /*2f*/ { "", 0, NONE8, 0, 0 }, | |||
| 203 | }; | |||
| 204 | ||||
| 205 | struct inst db_inst_0f3x[] = { | |||
| 206 | /*30*/ { "wrmsr", 0, NONE8, 0, 0 }, | |||
| 207 | /*31*/ { "rdtsc", 0, NONE8, 0, 0 }, | |||
| 208 | /*32*/ { "rdmsr", 0, NONE8, 0, 0 }, | |||
| 209 | /*33*/ { "rdpmc", 0, NONE8, 0, 0 }, | |||
| 210 | /*34*/ { "", 0, NONE8, 0, 0 }, | |||
| 211 | /*35*/ { "", 0, NONE8, 0, 0 }, | |||
| 212 | /*36*/ { "", 0, NONE8, 0, 0 }, | |||
| 213 | /*37*/ { "", 0, NONE8, 0, 0 }, | |||
| 214 | ||||
| 215 | /*38*/ { "", 0, NONE8, 0, 0 }, | |||
| 216 | /*39*/ { "", 0, NONE8, 0, 0 }, | |||
| 217 | /*3a*/ { "", 0, NONE8, 0, 0 }, | |||
| 218 | /*3b*/ { "", 0, NONE8, 0, 0 }, | |||
| 219 | /*3c*/ { "", 0, NONE8, 0, 0 }, | |||
| 220 | /*3d*/ { "", 0, NONE8, 0, 0 }, | |||
| 221 | /*3e*/ { "", 0, NONE8, 0, 0 }, | |||
| 222 | /*3f*/ { "", 0, NONE8, 0, 0 }, | |||
| 223 | }; | |||
| 224 | ||||
| 225 | struct inst db_inst_0f8x[] = { | |||
| 226 | /*80*/ { "jo", 0, NONE8, op1(Dl)(27), 0 }, | |||
| 227 | /*81*/ { "jno", 0, NONE8, op1(Dl)(27), 0 }, | |||
| 228 | /*82*/ { "jb", 0, NONE8, op1(Dl)(27), 0 }, | |||
| 229 | /*83*/ { "jnb", 0, NONE8, op1(Dl)(27), 0 }, | |||
| 230 | /*84*/ { "jz", 0, NONE8, op1(Dl)(27), 0 }, | |||
| 231 | /*85*/ { "jnz", 0, NONE8, op1(Dl)(27), 0 }, | |||
| 232 | /*86*/ { "jbe", 0, NONE8, op1(Dl)(27), 0 }, | |||
| 233 | /*87*/ { "jnbe", 0, NONE8, op1(Dl)(27), 0 }, | |||
| 234 | ||||
| 235 | /*88*/ { "js", 0, NONE8, op1(Dl)(27), 0 }, | |||
| 236 | /*89*/ { "jns", 0, NONE8, op1(Dl)(27), 0 }, | |||
| 237 | /*8a*/ { "jp", 0, NONE8, op1(Dl)(27), 0 }, | |||
| 238 | /*8b*/ { "jnp", 0, NONE8, op1(Dl)(27), 0 }, | |||
| 239 | /*8c*/ { "jl", 0, NONE8, op1(Dl)(27), 0 }, | |||
| 240 | /*8d*/ { "jnl", 0, NONE8, op1(Dl)(27), 0 }, | |||
| 241 | /*8e*/ { "jle", 0, NONE8, op1(Dl)(27), 0 }, | |||
| 242 | /*8f*/ { "jnle", 0, NONE8, op1(Dl)(27), 0 }, | |||
| 243 | }; | |||
| 244 | ||||
| 245 | struct inst db_inst_0f9x[] = { | |||
| 246 | /*90*/ { "seto", 1, NONE8, op1(Eb)(4), 0 }, | |||
| 247 | /*91*/ { "setno", 1, NONE8, op1(Eb)(4), 0 }, | |||
| 248 | /*92*/ { "setb", 1, NONE8, op1(Eb)(4), 0 }, | |||
| 249 | /*93*/ { "setnb", 1, NONE8, op1(Eb)(4), 0 }, | |||
| 250 | /*94*/ { "setz", 1, NONE8, op1(Eb)(4), 0 }, | |||
| 251 | /*95*/ { "setnz", 1, NONE8, op1(Eb)(4), 0 }, | |||
| 252 | /*96*/ { "setbe", 1, NONE8, op1(Eb)(4), 0 }, | |||
| 253 | /*97*/ { "setnbe",1, NONE8, op1(Eb)(4), 0 }, | |||
| 254 | ||||
| 255 | /*98*/ { "sets", 1, NONE8, op1(Eb)(4), 0 }, | |||
| 256 | /*99*/ { "setns", 1, NONE8, op1(Eb)(4), 0 }, | |||
| 257 | /*9a*/ { "setp", 1, NONE8, op1(Eb)(4), 0 }, | |||
| 258 | /*9b*/ { "setnp", 1, NONE8, op1(Eb)(4), 0 }, | |||
| 259 | /*9c*/ { "setl", 1, NONE8, op1(Eb)(4), 0 }, | |||
| 260 | /*9d*/ { "setnl", 1, NONE8, op1(Eb)(4), 0 }, | |||
| 261 | /*9e*/ { "setle", 1, NONE8, op1(Eb)(4), 0 }, | |||
| 262 | /*9f*/ { "setnle",1, NONE8, op1(Eb)(4), 0 }, | |||
| 263 | }; | |||
| 264 | ||||
| 265 | struct inst db_inst_0fax[] = { | |||
| 266 | /*a0*/ { "push", 0, QUAD3, op1(Si)(9), 0 }, | |||
| 267 | /*a1*/ { "pop", 0, QUAD3, op1(Si)(9), 0 }, | |||
| 268 | /*a2*/ { "cpuid", 0, NONE8, 0, 0 }, | |||
| 269 | /*a3*/ { "bt", 1, LONG2, op2(R,E)((5)|((1)<<8)), 0 }, | |||
| 270 | /*a4*/ { "shld", 1, LONG2, op3(Ib,R,E)((21)|((5)<<8)|((1)<<16)), 0 }, | |||
| 271 | /*a5*/ { "shld", 1, LONG2, op3(CL,R,E)((12)|((5)<<8)|((1)<<16)), 0 }, | |||
| 272 | /*a6*/ { NULL((void *)0), 1, NONE8, 0, db_GrpC }, | |||
| 273 | /*a7*/ { NULL((void *)0), 1, NONE8, 0, db_GrpB }, | |||
| 274 | ||||
| 275 | /*a8*/ { "push", 0, QUAD3, op1(Si)(9), 0 }, | |||
| 276 | /*a9*/ { "pop", 0, QUAD3, op1(Si)(9), 0 }, | |||
| 277 | /*aa*/ { "", 0, NONE8, 0, 0 }, | |||
| 278 | /*ab*/ { "bts", 1, LONG2, op2(R,E)((5)|((1)<<8)), 0 }, | |||
| 279 | /*ac*/ { "shrd", 1, LONG2, op3(Ib,E,R)((21)|((1)<<8)|((5)<<16)), 0 }, | |||
| 280 | /*ad*/ { "shrd", 1, LONG2, op3(CL,E,R)((12)|((1)<<8)|((5)<<16)), 0 }, | |||
| 281 | /*ae*/ { "", 1, RDEP9, op1(E)(1), db_Grp9 }, | |||
| 282 | /*af*/ { "imul", 1, LONG2, op2(E,R)((1)|((5)<<8)), 0 }, | |||
| 283 | }; | |||
| 284 | ||||
| 285 | struct inst db_inst_0fbx[] = { | |||
| 286 | /*b0*/ { "cmpxchg",1, BYTE0, op2(R, E)((5)|((1)<<8)), 0 }, | |||
| 287 | /*b1*/ { "cmpxchg",1, LONG2, op2(R, E)((5)|((1)<<8)), 0 }, | |||
| 288 | /*b2*/ { "lss", 1, LONG2, op2(E, R)((1)|((5)<<8)), 0 }, | |||
| 289 | /*b3*/ { "btr", 1, LONG2, op2(R, E)((5)|((1)<<8)), 0 }, | |||
| 290 | /*b4*/ { "lfs", 1, LONG2, op2(E, R)((1)|((5)<<8)), 0 }, | |||
| 291 | /*b5*/ { "lgs", 1, LONG2, op2(E, R)((1)|((5)<<8)), 0 }, | |||
| 292 | /*b6*/ { "movzb", 1, LONG2, op2(Eb, R)((4)|((5)<<8)), 0 }, | |||
| 293 | /*b7*/ { "movzw", 1, LONG2, op2(Ew, R)((3)|((5)<<8)), 0 }, | |||
| 294 | ||||
| 295 | /*b8*/ { "", 0, NONE8, 0, 0 }, | |||
| 296 | /*b9*/ { "", 0, NONE8, 0, 0 }, | |||
| 297 | /*ba*/ { NULL((void *)0), 1, LONG2, op2(Ib, E)((21)|((1)<<8)), db_Grp8 }, | |||
| 298 | /*bb*/ { "btc", 1, LONG2, op2(R, E)((5)|((1)<<8)), 0 }, | |||
| 299 | /*bc*/ { "bsf", 1, LONG2, op2(E, R)((1)|((5)<<8)), 0 }, | |||
| 300 | /*bd*/ { "bsr", 1, LONG2, op2(E, R)((1)|((5)<<8)), 0 }, | |||
| 301 | /*be*/ { "movsb", 1, LONG2, op2(Eb, R)((4)|((5)<<8)), 0 }, | |||
| 302 | /*bf*/ { "movsw", 1, LONG2, op2(Ew, R)((3)|((5)<<8)), 0 }, | |||
| 303 | }; | |||
| 304 | ||||
| 305 | struct inst db_inst_0fcx[] = { | |||
| 306 | /*c0*/ { "xadd", 1, BYTE0, op2(R, E)((5)|((1)<<8)), 0 }, | |||
| 307 | /*c1*/ { "xadd", 1, LONG2, op2(R, E)((5)|((1)<<8)), 0 }, | |||
| 308 | /*c2*/ { "", 0, NONE8, 0, 0 }, | |||
| 309 | /*c3*/ { "", 0, NONE8, 0, 0 }, | |||
| 310 | /*c4*/ { "", 0, NONE8, 0, 0 }, | |||
| 311 | /*c5*/ { "", 0, NONE8, 0, 0 }, | |||
| 312 | /*c6*/ { "", 0, NONE8, 0, 0 }, | |||
| 313 | /*c7*/ { NULL((void *)0), 1, NONE8, op1(E)(1), db_GrpA }, | |||
| 314 | ||||
| 315 | /*c8*/ { "bswap", 0, LONG2, op1(Ril)(36), 0 }, | |||
| 316 | /*c9*/ { "bswap", 0, LONG2, op1(Ril)(36), 0 }, | |||
| 317 | /*ca*/ { "bswap", 0, LONG2, op1(Ril)(36), 0 }, | |||
| 318 | /*cb*/ { "bswap", 0, LONG2, op1(Ril)(36), 0 }, | |||
| 319 | /*cc*/ { "bswap", 0, LONG2, op1(Ril)(36), 0 }, | |||
| 320 | /*cd*/ { "bswap", 0, LONG2, op1(Ril)(36), 0 }, | |||
| 321 | /*ce*/ { "bswap", 0, LONG2, op1(Ril)(36), 0 }, | |||
| 322 | /*cf*/ { "bswap", 0, LONG2, op1(Ril)(36), 0 }, | |||
| 323 | }; | |||
| 324 | ||||
| 325 | struct inst *db_inst_0f[] = { | |||
| 326 | db_inst_0f0x, | |||
| 327 | NULL((void *)0), | |||
| 328 | db_inst_0f2x, | |||
| 329 | db_inst_0f3x, | |||
| 330 | NULL((void *)0), | |||
| 331 | NULL((void *)0), | |||
| 332 | NULL((void *)0), | |||
| 333 | NULL((void *)0), | |||
| 334 | db_inst_0f8x, | |||
| 335 | db_inst_0f9x, | |||
| 336 | db_inst_0fax, | |||
| 337 | db_inst_0fbx, | |||
| 338 | db_inst_0fcx, | |||
| 339 | NULL((void *)0), | |||
| 340 | NULL((void *)0), | |||
| 341 | NULL((void *)0) | |||
| 342 | }; | |||
| 343 | ||||
| 344 | char * db_Esc92[] = { | |||
| 345 | "fnop", "", "", "", | |||
| 346 | "", "", "", "" | |||
| 347 | }; | |||
| 348 | char * db_Esc94[] = { | |||
| 349 | "fchs", "fabs", "", "", | |||
| 350 | "ftst", "fxam", "", "" | |||
| 351 | }; | |||
| 352 | char * db_Esc95[] = { | |||
| 353 | "fld1", "fldl2t", "fldl2e", "fldpi", | |||
| 354 | "fldlg2", "fldln2", "fldz", "" | |||
| 355 | }; | |||
| 356 | char * db_Esc96[] = { | |||
| 357 | "f2xm1", "fyl2x", "fptan", "fpatan", | |||
| 358 | "fxtract", "fprem1", "fdecstp", "fincstp" | |||
| 359 | }; | |||
| 360 | char * db_Esc97[] = { | |||
| 361 | "fprem", "fyl2xp1", "fsqrt", "fsincos", | |||
| 362 | "frndint", "fscale", "fsin", "fcos" | |||
| 363 | }; | |||
| 364 | ||||
| 365 | char * db_Esca5[] = { | |||
| 366 | "", "fucompp", "", "", | |||
| 367 | "", "", "", "" | |||
| 368 | }; | |||
| 369 | ||||
| 370 | char * db_Escb4[] = { | |||
| 371 | "fneni", "fndisi", "fnclex", "fninit", | |||
| 372 | "fsetpm", "", "", "" | |||
| 373 | }; | |||
| 374 | ||||
| 375 | char * db_Esce3[] = { | |||
| 376 | "", "fcompp", "", "", | |||
| 377 | "", "", "", "" | |||
| 378 | }; | |||
| 379 | ||||
| 380 | char * db_Escf4[] = { | |||
| 381 | "fnstsw", "", "", "", | |||
| 382 | "", "", "", "" | |||
| 383 | }; | |||
| 384 | ||||
| 385 | struct finst db_Esc8[] = { | |||
| 386 | /*0*/ { "fadd", SNGL4, op2(STI,ST)((32)|((31)<<8)), 0 }, | |||
| 387 | /*1*/ { "fmul", SNGL4, op2(STI,ST)((32)|((31)<<8)), 0 }, | |||
| 388 | /*2*/ { "fcom", SNGL4, op2(STI,ST)((32)|((31)<<8)), 0 }, | |||
| 389 | /*3*/ { "fcomp", SNGL4, op2(STI,ST)((32)|((31)<<8)), 0 }, | |||
| 390 | /*4*/ { "fsub", SNGL4, op2(STI,ST)((32)|((31)<<8)), 0 }, | |||
| 391 | /*5*/ { "fsubr", SNGL4, op2(STI,ST)((32)|((31)<<8)), 0 }, | |||
| 392 | /*6*/ { "fdiv", SNGL4, op2(STI,ST)((32)|((31)<<8)), 0 }, | |||
| 393 | /*7*/ { "fdivr", SNGL4, op2(STI,ST)((32)|((31)<<8)), 0 }, | |||
| 394 | }; | |||
| 395 | ||||
| 396 | struct finst db_Esc9[] = { | |||
| 397 | /*0*/ { "fld", SNGL4, op1(STI)(32), 0 }, | |||
| 398 | /*1*/ { "", NONE8, op1(STI)(32), "fxch" }, | |||
| 399 | /*2*/ { "fst", SNGL4, op1(X)(33), db_Esc92 }, | |||
| 400 | /*3*/ { "fstp", SNGL4, op1(X)(33), 0 }, | |||
| 401 | /*4*/ { "fldenv", NONE8, op1(X)(33), db_Esc94 }, | |||
| 402 | /*5*/ { "fldcw", NONE8, op1(X)(33), db_Esc95 }, | |||
| 403 | /*6*/ { "fnstenv",NONE8, op1(X)(33), db_Esc96 }, | |||
| 404 | /*7*/ { "fnstcw", NONE8, op1(X)(33), db_Esc97 }, | |||
| 405 | }; | |||
| 406 | ||||
| 407 | struct finst db_Esca[] = { | |||
| 408 | /*0*/ { "fiadd", LONG2, 0, 0 }, | |||
| 409 | /*1*/ { "fimul", LONG2, 0, 0 }, | |||
| 410 | /*2*/ { "ficom", LONG2, 0, 0 }, | |||
| 411 | /*3*/ { "ficomp", LONG2, 0, 0 }, | |||
| 412 | /*4*/ { "fisub", LONG2, op1(X)(33), 0 }, | |||
| 413 | /*5*/ { "fisubr", LONG2, 0, 0 }, | |||
| 414 | /*6*/ { "fidiv", LONG2, 0, 0 }, | |||
| 415 | /*7*/ { "fidivr", LONG2, 0, 0 } | |||
| 416 | }; | |||
| 417 | ||||
| 418 | struct finst db_Escb[] = { | |||
| 419 | /*0*/ { "fild", LONG2, 0, 0 }, | |||
| 420 | /*1*/ { "", NONE8, 0, 0 }, | |||
| 421 | /*2*/ { "fist", LONG2, 0, 0 }, | |||
| 422 | /*3*/ { "fistp", LONG2, 0, 0 }, | |||
| 423 | /*4*/ { "", WORD1, op1(X)(33), db_Escb4 }, | |||
| 424 | /*5*/ { "fld", EXTR6, 0, 0 }, | |||
| 425 | /*6*/ { "", WORD1, 0, 0 }, | |||
| 426 | /*7*/ { "fstp", EXTR6, 0, 0 }, | |||
| 427 | }; | |||
| 428 | ||||
| 429 | struct finst db_Escc[] = { | |||
| 430 | /*0*/ { "fadd", DBLR5, op2(ST,STI)((31)|((32)<<8)), 0 }, | |||
| 431 | /*1*/ { "fmul", DBLR5, op2(ST,STI)((31)|((32)<<8)), 0 }, | |||
| 432 | /*2*/ { "fcom", DBLR5, 0, 0 }, | |||
| 433 | /*3*/ { "fcomp", DBLR5, 0, 0 }, | |||
| 434 | /*4*/ { "fsub", DBLR5, op2(ST,STI)((31)|((32)<<8)), "fsubr" }, | |||
| 435 | /*5*/ { "fsubr", DBLR5, op2(ST,STI)((31)|((32)<<8)), "fsub" }, | |||
| 436 | /*6*/ { "fdiv", DBLR5, op2(ST,STI)((31)|((32)<<8)), "fdivr" }, | |||
| 437 | /*7*/ { "fdivr", DBLR5, op2(ST,STI)((31)|((32)<<8)), "fdiv" }, | |||
| 438 | }; | |||
| 439 | ||||
| 440 | struct finst db_Escd[] = { | |||
| 441 | /*0*/ { "fld", DBLR5, op1(STI)(32), "ffree" }, | |||
| 442 | /*1*/ { "", NONE8, 0, 0 }, | |||
| 443 | /*2*/ { "fst", DBLR5, op1(STI)(32), 0 }, | |||
| 444 | /*3*/ { "fstp", DBLR5, op1(STI)(32), 0 }, | |||
| 445 | /*4*/ { "frstor", NONE8, op1(STI)(32), "fucom" }, | |||
| 446 | /*5*/ { "", NONE8, op1(STI)(32), "fucomp" }, | |||
| 447 | /*6*/ { "fnsave", NONE8, 0, 0 }, | |||
| 448 | /*7*/ { "fnstsw", NONE8, 0, 0 }, | |||
| 449 | }; | |||
| 450 | ||||
| 451 | struct finst db_Esce[] = { | |||
| 452 | /*0*/ { "fiadd", WORD1, op2(ST,STI)((31)|((32)<<8)), "faddp" }, | |||
| 453 | /*1*/ { "fimul", WORD1, op2(ST,STI)((31)|((32)<<8)), "fmulp" }, | |||
| 454 | /*2*/ { "ficom", WORD1, 0, 0 }, | |||
| 455 | /*3*/ { "ficomp", WORD1, op1(X)(33), db_Esce3 }, | |||
| 456 | /*4*/ { "fisub", WORD1, op2(ST,STI)((31)|((32)<<8)), "fsubrp" }, | |||
| 457 | /*5*/ { "fisubr", WORD1, op2(ST,STI)((31)|((32)<<8)), "fsubp" }, | |||
| 458 | /*6*/ { "fidiv", WORD1, op2(ST,STI)((31)|((32)<<8)), "fdivrp" }, | |||
| 459 | /*7*/ { "fidivr", WORD1, op2(ST,STI)((31)|((32)<<8)), "fdivp" }, | |||
| 460 | }; | |||
| 461 | ||||
| 462 | struct finst db_Escf[] = { | |||
| 463 | /*0*/ { "fild", WORD1, 0, 0 }, | |||
| 464 | /*1*/ { "", WORD1, 0, 0 }, | |||
| 465 | /*2*/ { "fist", WORD1, 0, 0 }, | |||
| 466 | /*3*/ { "fistp", WORD1, 0, 0 }, | |||
| 467 | /*4*/ { "fbld", NONE8, op1(XA)(34), db_Escf4 }, | |||
| 468 | /*5*/ { "fild", QUAD3, 0, 0 }, | |||
| 469 | /*6*/ { "fbstp", NONE8, 0, 0 }, | |||
| 470 | /*7*/ { "fistp", QUAD3, 0, 0 }, | |||
| 471 | }; | |||
| 472 | ||||
| 473 | struct finst *db_Esc_inst[] = { | |||
| 474 | db_Esc8, db_Esc9, db_Esca, db_Escb, | |||
| 475 | db_Escc, db_Escd, db_Esce, db_Escf | |||
| 476 | }; | |||
| 477 | ||||
| 478 | char * db_Grp1[] = { | |||
| 479 | "add", | |||
| 480 | "or", | |||
| 481 | "adc", | |||
| 482 | "sbb", | |||
| 483 | "and", | |||
| 484 | "sub", | |||
| 485 | "xor", | |||
| 486 | "cmp" | |||
| 487 | }; | |||
| 488 | ||||
| 489 | char * db_Grp2[] = { | |||
| 490 | "rol", | |||
| 491 | "ror", | |||
| 492 | "rcl", | |||
| 493 | "rcr", | |||
| 494 | "shl", | |||
| 495 | "shr", | |||
| 496 | "shl", | |||
| 497 | "sar" | |||
| 498 | }; | |||
| 499 | ||||
| 500 | struct inst db_Grp3[] = { | |||
| 501 | { "test", 1, NONE8, op2(I,E)((19)|((1)<<8)), 0 }, | |||
| 502 | { "test", 1, NONE8, op2(I,E)((19)|((1)<<8)), 0 }, | |||
| 503 | { "not", 1, NONE8, op1(E)(1), 0 }, | |||
| 504 | { "neg", 1, NONE8, op1(E)(1), 0 }, | |||
| 505 | { "mul", 1, NONE8, op2(E,A)((1)|((10)<<8)), 0 }, | |||
| 506 | { "imul", 1, NONE8, op2(E,A)((1)|((10)<<8)), 0 }, | |||
| 507 | { "div", 1, NONE8, op2(E,A)((1)|((10)<<8)), 0 }, | |||
| 508 | { "idiv", 1, NONE8, op2(E,A)((1)|((10)<<8)), 0 }, | |||
| 509 | }; | |||
| 510 | ||||
| 511 | struct inst db_Grp4[] = { | |||
| 512 | { "inc", 1, BYTE0, op1(E)(1), 0 }, | |||
| 513 | { "dec", 1, BYTE0, op1(E)(1), 0 }, | |||
| 514 | { "", 1, NONE8, 0, 0 }, | |||
| 515 | { "", 1, NONE8, 0, 0 }, | |||
| 516 | { "", 1, NONE8, 0, 0 }, | |||
| 517 | { "", 1, NONE8, 0, 0 }, | |||
| 518 | { "", 1, NONE8, 0, 0 }, | |||
| 519 | { "", 1, NONE8, 0, 0 } | |||
| 520 | }; | |||
| 521 | ||||
| 522 | struct inst db_Grp5[] = { | |||
| 523 | { "inc", 1, LONG2, op1(E)(1), 0 }, | |||
| 524 | { "dec", 1, LONG2, op1(E)(1), 0 }, | |||
| 525 | { "call", 1, QUAD3, op1(Eind)(2),0 }, | |||
| 526 | { "lcall", 1, NONE8, op1(Eind)(2),0 }, | |||
| 527 | { "jmp", 1, NONE8, op1(Eind)(2),0 }, | |||
| 528 | { "ljmp", 1, NONE8, op1(Eind)(2),0 }, | |||
| 529 | { "push", 1, QUAD3, op1(E)(1), 0 }, | |||
| 530 | { "", 1, NONE8, 0, 0 } | |||
| 531 | }; | |||
| 532 | ||||
| 533 | struct inst db_inst_table[256] = { | |||
| 534 | /*00*/ { "add", 1, BYTE0, op2(R, E)((5)|((1)<<8)), 0 }, | |||
| 535 | /*01*/ { "add", 1, LONG2, op2(R, E)((5)|((1)<<8)), 0 }, | |||
| 536 | /*02*/ { "add", 1, BYTE0, op2(E, R)((1)|((5)<<8)), 0 }, | |||
| 537 | /*03*/ { "add", 1, LONG2, op2(E, R)((1)|((5)<<8)), 0 }, | |||
| 538 | /*04*/ { "add", 0, BYTE0, op2(I, A)((19)|((10)<<8)), 0 }, | |||
| 539 | /*05*/ { "add", 0, LONG2, op2(Is, A)((20)|((10)<<8)), 0 }, | |||
| 540 | /*06*/ { "", 0, NONE8, op1(Si)(9), 0 }, | |||
| 541 | /*07*/ { "", 0, NONE8, op1(Si)(9), 0 }, | |||
| 542 | ||||
| 543 | /*08*/ { "or", 1, BYTE0, op2(R, E)((5)|((1)<<8)), 0 }, | |||
| 544 | /*09*/ { "or", 1, LONG2, op2(R, E)((5)|((1)<<8)), 0 }, | |||
| 545 | /*0a*/ { "or", 1, BYTE0, op2(E, R)((1)|((5)<<8)), 0 }, | |||
| 546 | /*0b*/ { "or", 1, LONG2, op2(E, R)((1)|((5)<<8)), 0 }, | |||
| 547 | /*0c*/ { "or", 0, BYTE0, op2(I, A)((19)|((10)<<8)), 0 }, | |||
| 548 | /*0d*/ { "or", 0, LONG2, op2(I, A)((19)|((10)<<8)), 0 }, | |||
| 549 | /*0e*/ { "", 0, NONE8, op1(Si)(9), 0 }, | |||
| 550 | /*0f*/ { "", 0, NONE8, 0, 0 }, | |||
| 551 | ||||
| 552 | /*10*/ { "adc", 1, BYTE0, op2(R, E)((5)|((1)<<8)), 0 }, | |||
| 553 | /*11*/ { "adc", 1, LONG2, op2(R, E)((5)|((1)<<8)), 0 }, | |||
| 554 | /*12*/ { "adc", 1, BYTE0, op2(E, R)((1)|((5)<<8)), 0 }, | |||
| 555 | /*13*/ { "adc", 1, LONG2, op2(E, R)((1)|((5)<<8)), 0 }, | |||
| 556 | /*14*/ { "adc", 0, BYTE0, op2(I, A)((19)|((10)<<8)), 0 }, | |||
| 557 | /*15*/ { "adc", 0, LONG2, op2(Is, A)((20)|((10)<<8)), 0 }, | |||
| 558 | /*16*/ { "", 0, NONE8, op1(Si)(9), 0 }, | |||
| 559 | /*17*/ { "", 0, NONE8, op1(Si)(9), 0 }, | |||
| 560 | ||||
| 561 | /*18*/ { "sbb", 1, BYTE0, op2(R, E)((5)|((1)<<8)), 0 }, | |||
| 562 | /*19*/ { "sbb", 1, LONG2, op2(R, E)((5)|((1)<<8)), 0 }, | |||
| 563 | /*1a*/ { "sbb", 1, BYTE0, op2(E, R)((1)|((5)<<8)), 0 }, | |||
| 564 | /*1b*/ { "sbb", 1, LONG2, op2(E, R)((1)|((5)<<8)), 0 }, | |||
| 565 | /*1c*/ { "sbb", 0, BYTE0, op2(I, A)((19)|((10)<<8)), 0 }, | |||
| 566 | /*1d*/ { "sbb", 0, LONG2, op2(Is, A)((20)|((10)<<8)), 0 }, | |||
| 567 | /*1e*/ { "", 0, NONE8, op1(Si)(9), 0 }, | |||
| 568 | /*1f*/ { "", 0, NONE8, op1(Si)(9), 0 }, | |||
| 569 | ||||
| 570 | /*20*/ { "and", 1, BYTE0, op2(R, E)((5)|((1)<<8)), 0 }, | |||
| 571 | /*21*/ { "and", 1, LONG2, op2(R, E)((5)|((1)<<8)), 0 }, | |||
| 572 | /*22*/ { "and", 1, BYTE0, op2(E, R)((1)|((5)<<8)), 0 }, | |||
| 573 | /*23*/ { "and", 1, LONG2, op2(E, R)((1)|((5)<<8)), 0 }, | |||
| 574 | /*24*/ { "and", 0, BYTE0, op2(I, A)((19)|((10)<<8)), 0 }, | |||
| 575 | /*25*/ { "and", 0, LONG2, op2(I, A)((19)|((10)<<8)), 0 }, | |||
| 576 | /*26*/ { "", 0, NONE8, 0, 0 }, | |||
| 577 | /*27*/ { "", 0, NONE8, 0, 0 }, | |||
| 578 | ||||
| 579 | /*28*/ { "sub", 1, BYTE0, op2(R, E)((5)|((1)<<8)), 0 }, | |||
| 580 | /*29*/ { "sub", 1, LONG2, op2(R, E)((5)|((1)<<8)), 0 }, | |||
| 581 | /*2a*/ { "sub", 1, BYTE0, op2(E, R)((1)|((5)<<8)), 0 }, | |||
| 582 | /*2b*/ { "sub", 1, LONG2, op2(E, R)((1)|((5)<<8)), 0 }, | |||
| 583 | /*2c*/ { "sub", 0, BYTE0, op2(I, A)((19)|((10)<<8)), 0 }, | |||
| 584 | /*2d*/ { "sub", 0, LONG2, op2(Is, A)((20)|((10)<<8)), 0 }, | |||
| 585 | /*2e*/ { "", 0, NONE8, 0, 0 }, | |||
| 586 | /*2f*/ { "", 0, NONE8, 0, 0 }, | |||
| 587 | ||||
| 588 | /*30*/ { "xor", 1, BYTE0, op2(R, E)((5)|((1)<<8)), 0 }, | |||
| 589 | /*31*/ { "xor", 1, LONG2, op2(R, E)((5)|((1)<<8)), 0 }, | |||
| 590 | /*32*/ { "xor", 1, BYTE0, op2(E, R)((1)|((5)<<8)), 0 }, | |||
| 591 | /*33*/ { "xor", 1, LONG2, op2(E, R)((1)|((5)<<8)), 0 }, | |||
| 592 | /*34*/ { "xor", 0, BYTE0, op2(I, A)((19)|((10)<<8)), 0 }, | |||
| 593 | /*35*/ { "xor", 0, LONG2, op2(I, A)((19)|((10)<<8)), 0 }, | |||
| 594 | /*36*/ { "", 0, NONE8, 0, 0 }, | |||
| 595 | /*37*/ { "", 0, NONE8, 0, 0 }, | |||
| 596 | ||||
| 597 | /*38*/ { "cmp", 1, BYTE0, op2(R, E)((5)|((1)<<8)), 0 }, | |||
| 598 | /*39*/ { "cmp", 1, LONG2, op2(R, E)((5)|((1)<<8)), 0 }, | |||
| 599 | /*3a*/ { "cmp", 1, BYTE0, op2(E, R)((1)|((5)<<8)), 0 }, | |||
| 600 | /*3b*/ { "cmp", 1, LONG2, op2(E, R)((1)|((5)<<8)), 0 }, | |||
| 601 | /*3c*/ { "cmp", 0, BYTE0, op2(I, A)((19)|((10)<<8)), 0 }, | |||
| 602 | /*3d*/ { "cmp", 0, LONG2, op2(Is, A)((20)|((10)<<8)), 0 }, | |||
| 603 | /*3e*/ { "", 0, NONE8, 0, 0 }, | |||
| 604 | /*3f*/ { "", 0, NONE8, 0, 0 }, | |||
| 605 | ||||
| 606 | /*40*/ { "", 0, LONG2, op1(Ri)(7), 0 }, | |||
| 607 | /*41*/ { "", 0, LONG2, op1(Ri)(7), 0 }, | |||
| 608 | /*42*/ { "", 0, LONG2, op1(Ri)(7), 0 }, | |||
| 609 | /*43*/ { "", 0, LONG2, op1(Ri)(7), 0 }, | |||
| 610 | /*44*/ { "", 0, LONG2, op1(Ri)(7), 0 }, | |||
| 611 | /*45*/ { "", 0, LONG2, op1(Ri)(7), 0 }, | |||
| 612 | /*46*/ { "", 0, LONG2, op1(Ri)(7), 0 }, | |||
| 613 | /*47*/ { "", 0, LONG2, op1(Ri)(7), 0 }, | |||
| 614 | ||||
| 615 | /*48*/ { "", 0, LONG2, op1(Ri)(7), 0 }, | |||
| 616 | /*49*/ { "", 0, LONG2, op1(Ri)(7), 0 }, | |||
| 617 | /*4a*/ { "", 0, LONG2, op1(Ri)(7), 0 }, | |||
| 618 | /*4b*/ { "", 0, LONG2, op1(Ri)(7), 0 }, | |||
| 619 | /*4c*/ { "", 0, LONG2, op1(Ri)(7), 0 }, | |||
| 620 | /*4d*/ { "", 0, LONG2, op1(Ri)(7), 0 }, | |||
| 621 | /*4e*/ { "", 0, LONG2, op1(Ri)(7), 0 }, | |||
| 622 | /*4f*/ { "", 0, LONG2, op1(Ri)(7), 0 }, | |||
| 623 | ||||
| 624 | /*50*/ { "push", 0, QUAD3, op1(Ri)(7), 0 }, | |||
| 625 | /*51*/ { "push", 0, QUAD3, op1(Ri)(7), 0 }, | |||
| 626 | /*52*/ { "push", 0, QUAD3, op1(Ri)(7), 0 }, | |||
| 627 | /*53*/ { "push", 0, QUAD3, op1(Ri)(7), 0 }, | |||
| 628 | /*54*/ { "push", 0, QUAD3, op1(Ri)(7), 0 }, | |||
| 629 | /*55*/ { "push", 0, QUAD3, op1(Ri)(7), 0 }, | |||
| 630 | /*56*/ { "push", 0, QUAD3, op1(Ri)(7), 0 }, | |||
| 631 | /*57*/ { "push", 0, QUAD3, op1(Ri)(7), 0 }, | |||
| 632 | ||||
| 633 | /*58*/ { "pop", 0, QUAD3, op1(Ri)(7), 0 }, | |||
| 634 | /*59*/ { "pop", 0, QUAD3, op1(Ri)(7), 0 }, | |||
| 635 | /*5a*/ { "pop", 0, QUAD3, op1(Ri)(7), 0 }, | |||
| 636 | /*5b*/ { "pop", 0, QUAD3, op1(Ri)(7), 0 }, | |||
| 637 | /*5c*/ { "pop", 0, QUAD3, op1(Ri)(7), 0 }, | |||
| 638 | /*5d*/ { "pop", 0, QUAD3, op1(Ri)(7), 0 }, | |||
| 639 | /*5e*/ { "pop", 0, QUAD3, op1(Ri)(7), 0 }, | |||
| 640 | /*5f*/ { "pop", 0, QUAD3, op1(Ri)(7), 0 }, | |||
| 641 | ||||
| 642 | /*60*/ { "", 0, LONG2, 0, 0 }, | |||
| 643 | /*61*/ { "", 0, LONG2, 0, 0 }, | |||
| 644 | /*62*/ { "", 1, LONG2, op2(E, R)((1)|((5)<<8)), 0 }, | |||
| 645 | /*63*/ { "movsxd",1, LONG2, op2(E, R)((1)|((5)<<8)), 0 }, | |||
| 646 | /*64*/ { "", 0, NONE8, 0, 0 }, | |||
| 647 | /*65*/ { "", 0, NONE8, 0, 0 }, | |||
| 648 | /*66*/ { "", 0, NONE8, 0, 0 }, | |||
| 649 | /*67*/ { "", 0, NONE8, 0, 0 }, | |||
| 650 | ||||
| 651 | /*68*/ { "push", 0, QUAD3, op1(I)(19), 0 }, | |||
| 652 | /*69*/ { "imul", 1, LONG2, op3(I,E,R)((19)|((1)<<8)|((5)<<16)), 0 }, | |||
| 653 | /*6a*/ { "push", 0, QUAD3, op1(Ibs)(22), 0 }, | |||
| 654 | /*6b*/ { "imul", 1, LONG2, op3(Ibs,E,R)((22)|((1)<<8)|((5)<<16)),0 }, | |||
| 655 | /*6c*/ { "ins", 0, BYTE0, op2(DX, DI)((13)|((15)<<8)), 0 }, | |||
| 656 | /*6d*/ { "ins", 0, LONG2, op2(DX, DI)((13)|((15)<<8)), 0 }, | |||
| 657 | /*6e*/ { "outs", 0, BYTE0, op2(SI, DX)((14)|((13)<<8)), 0 }, | |||
| 658 | /*6f*/ { "outs", 0, LONG2, op2(SI, DX)((14)|((13)<<8)), 0 }, | |||
| 659 | ||||
| 660 | /*70*/ { "jo", 0, NONE8, op1(Db)(26), 0 }, | |||
| 661 | /*71*/ { "jno", 0, NONE8, op1(Db)(26), 0 }, | |||
| 662 | /*72*/ { "jb", 0, NONE8, op1(Db)(26), 0 }, | |||
| 663 | /*73*/ { "jnb", 0, NONE8, op1(Db)(26), 0 }, | |||
| 664 | /*74*/ { "jz", 0, NONE8, op1(Db)(26), 0 }, | |||
| 665 | /*75*/ { "jnz", 0, NONE8, op1(Db)(26), 0 }, | |||
| 666 | /*76*/ { "jbe", 0, NONE8, op1(Db)(26), 0 }, | |||
| 667 | /*77*/ { "jnbe", 0, NONE8, op1(Db)(26), 0 }, | |||
| 668 | ||||
| 669 | /*78*/ { "js", 0, NONE8, op1(Db)(26), 0 }, | |||
| 670 | /*79*/ { "jns", 0, NONE8, op1(Db)(26), 0 }, | |||
| 671 | /*7a*/ { "jp", 0, NONE8, op1(Db)(26), 0 }, | |||
| 672 | /*7b*/ { "jnp", 0, NONE8, op1(Db)(26), 0 }, | |||
| 673 | /*7c*/ { "jl", 0, NONE8, op1(Db)(26), 0 }, | |||
| 674 | /*7d*/ { "jnl", 0, NONE8, op1(Db)(26), 0 }, | |||
| 675 | /*7e*/ { "jle", 0, NONE8, op1(Db)(26), 0 }, | |||
| 676 | /*7f*/ { "jnle", 0, NONE8, op1(Db)(26), 0 }, | |||
| 677 | ||||
| 678 | /*80*/ { NULL((void *)0), 1, BYTE0, op2(I, E)((19)|((1)<<8)), db_Grp1 }, | |||
| 679 | /*81*/ { NULL((void *)0), 1, LONG2, op2(I, E)((19)|((1)<<8)), db_Grp1 }, | |||
| 680 | /*82*/ { NULL((void *)0), 1, BYTE0, op2(I, E)((19)|((1)<<8)), db_Grp1 }, | |||
| 681 | /*83*/ { NULL((void *)0), 1, LONG2, op2(Ibs,E)((22)|((1)<<8)), db_Grp1 }, | |||
| 682 | /*84*/ { "test", 1, BYTE0, op2(R, E)((5)|((1)<<8)), 0 }, | |||
| 683 | /*85*/ { "test", 1, LONG2, op2(R, E)((5)|((1)<<8)), 0 }, | |||
| 684 | /*86*/ { "xchg", 1, BYTE0, op2(R, E)((5)|((1)<<8)), 0 }, | |||
| 685 | /*87*/ { "xchg", 1, LONG2, op2(R, E)((5)|((1)<<8)), 0 }, | |||
| 686 | ||||
| 687 | /*88*/ { "mov", 1, BYTE0, op2(R, E)((5)|((1)<<8)), 0 }, | |||
| 688 | /*89*/ { "mov", 1, LONG2, op2(R, E)((5)|((1)<<8)), 0 }, | |||
| 689 | /*8a*/ { "mov", 1, BYTE0, op2(E, R)((1)|((5)<<8)), 0 }, | |||
| 690 | /*8b*/ { "mov", 1, LONG2, op2(E, R)((1)|((5)<<8)), 0 }, | |||
| 691 | /*8c*/ { "mov", 1, NONE8, op2(S, Ew)((8)|((3)<<8)), 0 }, | |||
| 692 | /*8d*/ { "lea", 1, LONG2, op2(E, R)((1)|((5)<<8)), 0 }, | |||
| 693 | /*8e*/ { "mov", 1, NONE8, op2(Ew, S)((3)|((8)<<8)), 0 }, | |||
| 694 | /*8f*/ { "pop", 1, QUAD3, op1(Dl)(27), 0 }, | |||
| 695 | ||||
| 696 | /*90*/ { "nop", 0, NONE8, 0, 0 }, | |||
| 697 | /*91*/ { "xchg", 0, LONG2, op2(A, Ri)((10)|((7)<<8)), 0 }, | |||
| 698 | /*92*/ { "xchg", 0, LONG2, op2(A, Ri)((10)|((7)<<8)), 0 }, | |||
| 699 | /*93*/ { "xchg", 0, LONG2, op2(A, Ri)((10)|((7)<<8)), 0 }, | |||
| 700 | /*94*/ { "xchg", 0, LONG2, op2(A, Ri)((10)|((7)<<8)), 0 }, | |||
| 701 | /*95*/ { "xchg", 0, LONG2, op2(A, Ri)((10)|((7)<<8)), 0 }, | |||
| 702 | /*96*/ { "xchg", 0, LONG2, op2(A, Ri)((10)|((7)<<8)), 0 }, | |||
| 703 | /*97*/ { "xchg", 0, LONG2, op2(A, Ri)((10)|((7)<<8)), 0 }, | |||
| 704 | ||||
| 705 | /*98*/ { "cbw", 0, SDEP7, 0, "cwde\0cdqe" }, | |||
| 706 | /*99*/ { "cwd", 0, SDEP7, 0, "cdq\0cqo" }, | |||
| 707 | /*9a*/ { "", 0, NONE8, op1(OS)(30), 0 }, | |||
| 708 | /*9b*/ { "wait", 0, NONE8, 0, 0 }, | |||
| 709 | /*9c*/ { "pushf", 0, QUAD3, 0, 0 }, | |||
| 710 | /*9d*/ { "popf", 0, QUAD3, 0, 0 }, | |||
| 711 | /*9e*/ { "sahf", 0, NONE8, 0, 0 }, | |||
| 712 | /*9f*/ { "lahf", 0, NONE8, 0, 0 }, | |||
| 713 | ||||
| 714 | /*a0*/ { "mov", 0, BYTE0, op2(O, A)((25)|((10)<<8)), 0 }, | |||
| 715 | /*a1*/ { "mov", 0, LONG2, op2(O, A)((25)|((10)<<8)), 0 }, | |||
| 716 | /*a2*/ { "mov", 0, BYTE0, op2(A, O)((10)|((25)<<8)), 0 }, | |||
| 717 | /*a3*/ { "mov", 0, LONG2, op2(A, O)((10)|((25)<<8)), 0 }, | |||
| 718 | /*a4*/ { "movs", 0, BYTE0, op2(SI,DI)((14)|((15)<<8)), 0 }, | |||
| 719 | /*a5*/ { "movs", 0, LONG2, op2(SI,DI)((14)|((15)<<8)), 0 }, | |||
| 720 | /*a6*/ { "cmps", 0, BYTE0, op2(SI,DI)((14)|((15)<<8)), 0 }, | |||
| 721 | /*a7*/ { "cmps", 0, LONG2, op2(SI,DI)((14)|((15)<<8)), 0 }, | |||
| 722 | ||||
| 723 | /*a8*/ { "test", 0, BYTE0, op2(I, A)((19)|((10)<<8)), 0 }, | |||
| 724 | /*a9*/ { "test", 0, LONG2, op2(I, A)((19)|((10)<<8)), 0 }, | |||
| 725 | /*aa*/ { "stos", 0, BYTE0, op1(DI)(15), 0 }, | |||
| 726 | /*ab*/ { "stos", 0, LONG2, op1(DI)(15), 0 }, | |||
| 727 | /*ac*/ { "lods", 0, BYTE0, op1(SI)(14), 0 }, | |||
| 728 | /*ad*/ { "lods", 0, LONG2, op1(SI)(14), 0 }, | |||
| 729 | /*ae*/ { "scas", 0, BYTE0, op1(SI)(14), 0 }, | |||
| 730 | /*af*/ { "scas", 0, LONG2, op1(SI)(14), 0 }, | |||
| 731 | ||||
| 732 | /*b0*/ { "mov", 0, BYTE0, op2(I, Ri)((19)|((7)<<8)), 0 }, | |||
| 733 | /*b1*/ { "mov", 0, BYTE0, op2(I, Ri)((19)|((7)<<8)), 0 }, | |||
| 734 | /*b2*/ { "mov", 0, BYTE0, op2(I, Ri)((19)|((7)<<8)), 0 }, | |||
| 735 | /*b3*/ { "mov", 0, BYTE0, op2(I, Ri)((19)|((7)<<8)), 0 }, | |||
| 736 | /*b4*/ { "mov", 0, BYTE0, op2(I, Ri)((19)|((7)<<8)), 0 }, | |||
| 737 | /*b5*/ { "mov", 0, BYTE0, op2(I, Ri)((19)|((7)<<8)), 0 }, | |||
| 738 | /*b6*/ { "mov", 0, BYTE0, op2(I, Ri)((19)|((7)<<8)), 0 }, | |||
| 739 | /*b7*/ { "mov", 0, BYTE0, op2(I, Ri)((19)|((7)<<8)), 0 }, | |||
| 740 | ||||
| 741 | /*b8*/ { "mov", 0, LONG2, op2(I, Ri)((19)|((7)<<8)), 0 }, | |||
| 742 | /*b9*/ { "mov", 0, LONG2, op2(I, Ri)((19)|((7)<<8)), 0 }, | |||
| 743 | /*ba*/ { "mov", 0, LONG2, op2(I, Ri)((19)|((7)<<8)), 0 }, | |||
| 744 | /*bb*/ { "mov", 0, LONG2, op2(I, Ri)((19)|((7)<<8)), 0 }, | |||
| 745 | /*bc*/ { "mov", 0, LONG2, op2(I, Ri)((19)|((7)<<8)), 0 }, | |||
| 746 | /*bd*/ { "mov", 0, LONG2, op2(I, Ri)((19)|((7)<<8)), 0 }, | |||
| 747 | /*be*/ { "mov", 0, LONG2, op2(I, Ri)((19)|((7)<<8)), 0 }, | |||
| 748 | /*bf*/ { "mov", 0, LONG2, op2(I, Ri)((19)|((7)<<8)), 0 }, | |||
| 749 | ||||
| 750 | /*c0*/ { NULL((void *)0), 1, BYTE0, op2(Ib, E)((21)|((1)<<8)), db_Grp2 }, | |||
| 751 | /*c1*/ { NULL((void *)0), 1, LONG2, op2(Ib, E)((21)|((1)<<8)), db_Grp2 }, | |||
| 752 | /*c2*/ { "ret", 0, NONE8, op1(Iw)(23), 0 }, | |||
| 753 | /*c3*/ { "ret", 0, NONE8, 0, 0 }, | |||
| 754 | /*c4*/ { "", 1, LONG2, op2(E, R)((1)|((5)<<8)), 0 }, | |||
| 755 | /*c5*/ { "", 1, LONG2, op2(E, R)((1)|((5)<<8)), 0 }, | |||
| 756 | /*c6*/ { "mov", 1, BYTE0, op2(I, E)((19)|((1)<<8)), 0 }, | |||
| 757 | /*c7*/ { "mov", 1, LONG2, op2(I, E)((19)|((1)<<8)), 0 }, | |||
| 758 | ||||
| 759 | /*c8*/ { "enter", 0, NONE8, op2(Iq, Ib)((24)|((21)<<8)), 0 }, | |||
| 760 | /*c9*/ { "leave", 0, NONE8, 0, 0 }, | |||
| 761 | /*ca*/ { "lret", 0, NONE8, op1(Iw)(23), 0 }, | |||
| 762 | /*cb*/ { "lret", 0, NONE8, 0, 0 }, | |||
| 763 | /*cc*/ { "int", 0, NONE8, op1(o3)(29), 0 }, | |||
| 764 | /*cd*/ { "int", 0, NONE8, op1(Ib)(21), 0 }, | |||
| 765 | /*ce*/ { "", 0, NONE8, 0, 0 }, | |||
| 766 | /*cf*/ { "iret", 0, NONE8, 0, 0 }, | |||
| 767 | ||||
| 768 | /*d0*/ { NULL((void *)0), 1, BYTE0, op2(o1, E)((28)|((1)<<8)), db_Grp2 }, | |||
| 769 | /*d1*/ { NULL((void *)0), 1, LONG2, op2(o1, E)((28)|((1)<<8)), db_Grp2 }, | |||
| 770 | /*d2*/ { NULL((void *)0), 1, BYTE0, op2(CL, E)((12)|((1)<<8)), db_Grp2 }, | |||
| 771 | /*d3*/ { NULL((void *)0), 1, LONG2, op2(CL, E)((12)|((1)<<8)), db_Grp2 }, | |||
| 772 | /*d4*/ { "", 1, NONE8, op1(Iba)(37), 0 }, | |||
| 773 | /*d5*/ { "", 1, NONE8, op1(Iba)(37), 0 }, | |||
| 774 | /*d6*/ { ".byte\t0xd6",0, NONE8, 0, 0 }, | |||
| 775 | /*d7*/ { "xlat", 0, BYTE0, op1(BX)(11), 0 }, | |||
| 776 | ||||
| 777 | /* d8 to df block is ignored: direct test in code handles them */ | |||
| 778 | /*d8*/ { "", 1, NONE8, 0, db_Esc8 }, | |||
| 779 | /*d9*/ { "", 1, NONE8, 0, db_Esc9 }, | |||
| 780 | /*da*/ { "", 1, NONE8, 0, db_Esca }, | |||
| 781 | /*db*/ { "", 1, NONE8, 0, db_Escb }, | |||
| 782 | /*dc*/ { "", 1, NONE8, 0, db_Escc }, | |||
| 783 | /*dd*/ { "", 1, NONE8, 0, db_Escd }, | |||
| 784 | /*de*/ { "", 1, NONE8, 0, db_Esce }, | |||
| 785 | /*df*/ { "", 1, NONE8, 0, db_Escf }, | |||
| 786 | ||||
| 787 | /*e0*/ { "loopne",0, NONE8, op1(Db)(26), 0 }, | |||
| 788 | /*e1*/ { "loope", 0, NONE8, op1(Db)(26), 0 }, | |||
| 789 | /*e2*/ { "loop", 0, NONE8, op1(Db)(26), 0 }, | |||
| 790 | /*e3*/ { "jcxz", 0, SDEP7, op1(Db)(26), "jecxz\0jrcxz" }, | |||
| 791 | /*e4*/ { "in", 0, BYTE0, op2(Ib, A)((21)|((10)<<8)), 0 }, | |||
| 792 | /*e5*/ { "in", 0, LONG2, op2(Ib, A)((21)|((10)<<8)) , 0 }, | |||
| 793 | /*e6*/ { "out", 0, BYTE0, op2(A, Ib)((10)|((21)<<8)), 0 }, | |||
| 794 | /*e7*/ { "out", 0, LONG2, op2(A, Ib)((10)|((21)<<8)) , 0 }, | |||
| 795 | ||||
| 796 | /*e8*/ { "call", 0, QUAD3, op1(Dl)(27), 0 }, | |||
| 797 | /*e9*/ { "jmp", 0, NONE8, op1(Dl)(27), 0 }, | |||
| 798 | /*ea*/ { "", 0, NONE8, op1(OS)(30), 0 }, | |||
| 799 | /*eb*/ { "jmp", 0, NONE8, op1(Db)(26), 0 }, | |||
| 800 | /*ec*/ { "in", 0, BYTE0, op2(DX, A)((13)|((10)<<8)), 0 }, | |||
| 801 | /*ed*/ { "in", 0, LONG2, op2(DX, A)((13)|((10)<<8)) , 0 }, | |||
| 802 | /*ee*/ { "out", 0, BYTE0, op2(A, DX)((10)|((13)<<8)), 0 }, | |||
| 803 | /*ef*/ { "out", 0, LONG2, op2(A, DX)((10)|((13)<<8)) , 0 }, | |||
| 804 | ||||
| 805 | /*f0*/ { "", 0, NONE8, 0, 0 }, | |||
| 806 | /*f1*/ { "", 0, NONE8, 0, 0 }, | |||
| 807 | /*f2*/ { "", 0, NONE8, 0, 0 }, | |||
| 808 | /*f3*/ { "", 0, NONE8, 0, 0 }, | |||
| 809 | /*f4*/ { "hlt", 0, NONE8, 0, 0 }, | |||
| 810 | /*f5*/ { "cmc", 0, NONE8, 0, 0 }, | |||
| 811 | /*f6*/ { "", 1, BYTE0, 0, db_Grp3 }, | |||
| 812 | /*f7*/ { "", 1, LONG2, 0, db_Grp3 }, | |||
| 813 | ||||
| 814 | /*f8*/ { "clc", 0, NONE8, 0, 0 }, | |||
| 815 | /*f9*/ { "stc", 0, NONE8, 0, 0 }, | |||
| 816 | /*fa*/ { "cli", 0, NONE8, 0, 0 }, | |||
| 817 | /*fb*/ { "sti", 0, NONE8, 0, 0 }, | |||
| 818 | /*fc*/ { "cld", 0, NONE8, 0, 0 }, | |||
| 819 | /*fd*/ { "std", 0, NONE8, 0, 0 }, | |||
| 820 | /*fe*/ { "", 1, RDEP9, 0, db_Grp4 }, | |||
| 821 | /*ff*/ { "", 1, RDEP9, 0, db_Grp5 }, | |||
| 822 | }; | |||
| 823 | ||||
| 824 | struct inst db_bad_inst = | |||
| 825 | { "???", 0, NONE8, 0, 0 } | |||
| 826 | ; | |||
| 827 | ||||
| 828 | #define REX_W(rex)(((rex) & 0x8) == 0x8) (((rex) & 0x8) == 0x8) /* 64-bit operand size */ | |||
| 829 | #define REX_R(rex)(((rex) & 0x4) << 1) (((rex) & 0x4) << 1) /* ModRM reg field extension */ | |||
| 830 | #define REX_X(rex)(((rex) & 0x2) << 2) (((rex) & 0x2) << 2) /* SIB index field extension */ | |||
| 831 | #define REX_B(rex)(((rex) & 0x1) << 3) (((rex) & 0x1) << 3) /* ModRM r/m and SIB base ext */ | |||
| 832 | ||||
| 833 | #define f_mod(byte)((byte)>>6) ((byte)>>6) | |||
| 834 | #define f_reg(byte, rex)((((byte)>>3)&0x7) + (((rex) & 0x4) << 1) ) ((((byte)>>3)&0x7) + REX_R(rex)(((rex) & 0x4) << 1)) | |||
| 835 | #define f_rm(byte, rex)(((byte)&0x7) + (((rex) & 0x1) << 3)) (((byte)&0x7) + REX_B(rex)(((rex) & 0x1) << 3)) | |||
| 836 | ||||
| 837 | #define sib_ss(byte)((byte)>>6) ((byte)>>6) | |||
| 838 | #define sib_index(byte, rex)((((byte)>>3)&0x7) + (((rex) & 0x2) << 2) ) ((((byte)>>3)&0x7) + REX_X(rex)(((rex) & 0x2) << 2)) | |||
| 839 | #define sib_base(byte, rex)(((byte)&0x7) + (((rex) & 0x1) << 3)) (((byte)&0x7) + REX_B(rex)(((rex) & 0x1) << 3)) | |||
| 840 | ||||
| 841 | struct i_addr { | |||
| 842 | int is_reg; /* if reg, reg number is in 'disp' */ | |||
| 843 | int disp; | |||
| 844 | char * base; | |||
| 845 | char * index; | |||
| 846 | int ss; | |||
| 847 | }; | |||
| 848 | ||||
| 849 | char * db_index_reg_16[8] = { | |||
| 850 | "%bx,%si", | |||
| 851 | "%bx,%di", | |||
| 852 | "%bp,%si", | |||
| 853 | "%bp,%di", | |||
| 854 | "%si", | |||
| 855 | "%di", | |||
| 856 | "%bp", | |||
| 857 | "%bx" | |||
| 858 | }; | |||
| 859 | ||||
| 860 | char * db_reg[4][16] = { | |||
| 861 | { "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh", | |||
| 862 | "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"}, | |||
| 863 | { "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di", | |||
| 864 | "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"}, | |||
| 865 | { "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi", | |||
| 866 | "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"}, | |||
| 867 | { "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi", | |||
| 868 | "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15" } | |||
| 869 | }; | |||
| 870 | ||||
| 871 | char * db_seg_reg[8] = { | |||
| 872 | "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "", "" | |||
| 873 | }; | |||
| 874 | ||||
| 875 | /* | |||
| 876 | * lengths for size attributes | |||
| 877 | */ | |||
| 878 | int db_lengths[] = { | |||
| 879 | 1, /* BYTE */ | |||
| 880 | 2, /* WORD */ | |||
| 881 | 4, /* LONG */ | |||
| 882 | 8, /* QUAD */ | |||
| 883 | 4, /* SNGL */ | |||
| 884 | 8, /* DBLR */ | |||
| 885 | 10, /* EXTR */ | |||
| 886 | }; | |||
| 887 | ||||
| 888 | #define get_value_inc(result, loc, size, is_signed)do { result = db_get_value((loc), (size), (is_signed)); (loc) += (size); } while (0) \ | |||
| 889 | do { \ | |||
| 890 | result = db_get_value((loc), (size), (is_signed)); \ | |||
| 891 | (loc) += (size); \ | |||
| 892 | } while (0) | |||
| 893 | ||||
| 894 | ||||
| 895 | vaddr_t db_read_address(vaddr_t, int, int, int, struct i_addr *); | |||
| 896 | void db_print_address(char *, int, struct i_addr *); | |||
| 897 | vaddr_t db_disasm_esc(vaddr_t, int, int, int, int, char *); | |||
| 898 | vaddr_t db_disasm_3dnow(vaddr_t, int, int, int, char *); | |||
| 899 | ||||
| 900 | /* | |||
| 901 | * Read address at location and return updated location. | |||
| 902 | */ | |||
| 903 | vaddr_t | |||
| 904 | db_read_address(vaddr_t loc, int short_addr, int regmodrm, int rex, | |||
| 905 | struct i_addr *addrp) | |||
| 906 | { | |||
| 907 | int mod, rm, sib, index, disp, size; | |||
| 908 | ||||
| 909 | size = (short_addr ? LONG2 : QUAD3); | |||
| 910 | mod = f_mod(regmodrm)((regmodrm)>>6); | |||
| 911 | rm = f_rm(regmodrm, rex)(((regmodrm)&0x7) + (((rex) & 0x1) << 3)); | |||
| 912 | ||||
| 913 | if (mod == 3) { | |||
| 914 | addrp->is_reg = 1; | |||
| 915 | addrp->disp = rm; | |||
| 916 | return (loc); | |||
| 917 | } | |||
| 918 | addrp->is_reg = 0; | |||
| 919 | addrp->index = 0; | |||
| 920 | ||||
| 921 | if (rm == 4 || rm == 12) { | |||
| 922 | get_value_inc(sib, loc, 1, 0)do { sib = db_get_value((loc), (1), (0)); (loc) += (1); } while (0); | |||
| 923 | rm = sib_base(sib, rex)(((sib)&0x7) + (((rex) & 0x1) << 3)); | |||
| 924 | index = sib_index(sib, rex)((((sib)>>3)&0x7) + (((rex) & 0x2) << 2)); | |||
| 925 | if (index != 4) | |||
| 926 | addrp->index = db_reg[size][index]; | |||
| 927 | addrp->ss = sib_ss(sib)((sib)>>6); | |||
| 928 | } | |||
| 929 | ||||
| 930 | switch (mod) { | |||
| 931 | case 0: | |||
| 932 | if (rm == 5) { | |||
| 933 | get_value_inc(addrp->disp, loc, 4, 0)do { addrp->disp = db_get_value((loc), (4), (0)); (loc) += (4); } while (0); | |||
| 934 | addrp->base = 0; | |||
| 935 | } else { | |||
| 936 | addrp->disp = 0; | |||
| 937 | addrp->base = db_reg[size][rm]; | |||
| 938 | } | |||
| 939 | break; | |||
| 940 | case 1: | |||
| 941 | get_value_inc(disp, loc, 1, 1)do { disp = db_get_value((loc), (1), (1)); (loc) += (1); } while (0); | |||
| 942 | addrp->disp = disp; | |||
| 943 | addrp->base = db_reg[size][rm]; | |||
| 944 | break; | |||
| 945 | case 2: | |||
| 946 | get_value_inc(disp, loc, 4, 0)do { disp = db_get_value((loc), (4), (0)); (loc) += (4); } while (0); | |||
| 947 | addrp->disp = disp; | |||
| 948 | addrp->base = db_reg[size][rm]; | |||
| 949 | break; | |||
| 950 | } | |||
| 951 | return (loc); | |||
| 952 | } | |||
| 953 | ||||
| 954 | void | |||
| 955 | db_print_address(char *seg, int size, struct i_addr *addrp) | |||
| 956 | { | |||
| 957 | if (addrp->is_reg) { | |||
| ||||
| 958 | db_printf("%s", db_reg[size][addrp->disp]); | |||
| 959 | return; | |||
| 960 | } | |||
| 961 | ||||
| 962 | if (seg) | |||
| 963 | db_printf("%s:", seg); | |||
| 964 | ||||
| 965 | db_printsym((vaddr_t)addrp->disp, DB_STGY_ANY0, db_printf); | |||
| 966 | if (addrp->base != 0 || addrp->index != 0) { | |||
| 967 | db_printf("("); | |||
| 968 | if (addrp->base) | |||
| 969 | db_printf("%s", addrp->base); | |||
| 970 | if (addrp->index) | |||
| 971 | db_printf(",%s,%d", addrp->index, 1<<addrp->ss); | |||
| 972 | db_printf(")"); | |||
| 973 | } | |||
| 974 | } | |||
| 975 | ||||
| 976 | /* | |||
| 977 | * Disassemble 3DNow! instruction and return updated location. | |||
| 978 | */ | |||
| 979 | vaddr_t | |||
| 980 | db_disasm_3dnow(vaddr_t loc, int short_addr, int size, int rex, char *seg) | |||
| 981 | { | |||
| 982 | int regmodrm, sib, displacement, opcode; | |||
| 983 | ||||
| 984 | get_value_inc(regmodrm, loc, 1, 0)do { regmodrm = db_get_value((loc), (1), (0)); (loc) += (1); } while (0); | |||
| 985 | get_value_inc(sib, loc, 1, 0)do { sib = db_get_value((loc), (1), (0)); (loc) += (1); } while (0); | |||
| 986 | get_value_inc(displacement, loc, 1, 0)do { displacement = db_get_value((loc), (1), (0)); (loc) += ( 1); } while (0); | |||
| 987 | get_value_inc(opcode, loc, 1, 0)do { opcode = db_get_value((loc), (1), (0)); (loc) += (1); } while (0); | |||
| 988 | ||||
| 989 | /* XXX fix later... */ | |||
| 990 | db_printf("<3DNow! instruction>"); | |||
| 991 | ||||
| 992 | return (loc); | |||
| 993 | } | |||
| 994 | ||||
| 995 | /* | |||
| 996 | * Disassemble floating-point ("escape") instruction | |||
| 997 | * and return updated location. | |||
| 998 | */ | |||
| 999 | vaddr_t | |||
| 1000 | db_disasm_esc(vaddr_t loc, int inst, int short_addr, int size, int rex, | |||
| 1001 | char *seg) | |||
| 1002 | { | |||
| 1003 | int regmodrm; | |||
| 1004 | struct finst *fp; | |||
| 1005 | int mod; | |||
| 1006 | struct i_addr address; | |||
| 1007 | char * name; | |||
| 1008 | ||||
| 1009 | get_value_inc(regmodrm, loc, 1, 0)do { regmodrm = db_get_value((loc), (1), (0)); (loc) += (1); } while (0); | |||
| 1010 | fp = &db_Esc_inst[inst - 0xd8][f_reg(regmodrm, 0)((((regmodrm)>>3)&0x7) + (((0) & 0x4) << 1 ))]; | |||
| 1011 | mod = f_mod(regmodrm)((regmodrm)>>6); | |||
| 1012 | if (mod != 3) { | |||
| 1013 | if (*fp->f_name == '\0') { | |||
| 1014 | db_printf("<bad instruction>"); | |||
| 1015 | return (loc); | |||
| 1016 | } | |||
| 1017 | ||||
| 1018 | /* | |||
| 1019 | * Normal address modes. | |||
| 1020 | */ | |||
| 1021 | loc = db_read_address(loc, short_addr, regmodrm, rex, &address); | |||
| 1022 | db_printf("%s", fp->f_name); | |||
| 1023 | switch (fp->f_size) { | |||
| 1024 | case SNGL4: | |||
| 1025 | db_printf("s"); | |||
| 1026 | break; | |||
| 1027 | case DBLR5: | |||
| 1028 | db_printf("l"); | |||
| 1029 | break; | |||
| 1030 | case EXTR6: | |||
| 1031 | db_printf("t"); | |||
| 1032 | break; | |||
| 1033 | case WORD1: | |||
| 1034 | db_printf("s"); | |||
| 1035 | break; | |||
| 1036 | case LONG2: | |||
| 1037 | db_printf("l"); | |||
| 1038 | break; | |||
| 1039 | case QUAD3: | |||
| 1040 | db_printf("q"); | |||
| 1041 | break; | |||
| 1042 | default: | |||
| 1043 | break; | |||
| 1044 | } | |||
| 1045 | db_printf("\t"); | |||
| 1046 | db_print_address(seg, BYTE0, &address); | |||
| 1047 | } else { | |||
| 1048 | /* | |||
| 1049 | * 'reg-reg' - special formats | |||
| 1050 | */ | |||
| 1051 | switch (fp->f_rrmode) { | |||
| 1052 | case op2(ST,STI)((31)|((32)<<8)): | |||
| 1053 | name = (fp->f_rrname) ? fp->f_rrname : fp->f_name; | |||
| 1054 | db_printf("%s\t%%st,%%st(%d)",name, f_rm(regmodrm, 0)(((regmodrm)&0x7) + (((0) & 0x1) << 3))); | |||
| 1055 | break; | |||
| 1056 | case op2(STI,ST)((32)|((31)<<8)): | |||
| 1057 | name = (fp->f_rrname) ? fp->f_rrname : fp->f_name; | |||
| 1058 | db_printf("%s\t%%st(%d),%%st",name, f_rm(regmodrm, 0)(((regmodrm)&0x7) + (((0) & 0x1) << 3))); | |||
| 1059 | break; | |||
| 1060 | case op1(STI)(32): | |||
| 1061 | name = (fp->f_rrname) ? fp->f_rrname : fp->f_name; | |||
| 1062 | db_printf("%s\t%%st(%d)",name, f_rm(regmodrm, 0)(((regmodrm)&0x7) + (((0) & 0x1) << 3))); | |||
| 1063 | break; | |||
| 1064 | case op1(X)(33): | |||
| 1065 | name = ((char * const *)fp->f_rrname)[f_rm(regmodrm,0)(((regmodrm)&0x7) + (((0) & 0x1) << 3))]; | |||
| 1066 | if (*name == '\0') | |||
| 1067 | goto bad; | |||
| 1068 | db_printf("%s", name); | |||
| 1069 | break; | |||
| 1070 | case op1(XA)(34): | |||
| 1071 | name = ((char * const *)fp->f_rrname)[f_rm(regmodrm,0)(((regmodrm)&0x7) + (((0) & 0x1) << 3))]; | |||
| 1072 | if (*name == '\0') | |||
| 1073 | goto bad; | |||
| 1074 | db_printf("%s\t%%ax", name); | |||
| 1075 | break; | |||
| 1076 | default: | |||
| 1077 | bad: | |||
| 1078 | db_printf("<bad instruction>"); | |||
| 1079 | break; | |||
| 1080 | } | |||
| 1081 | } | |||
| 1082 | ||||
| 1083 | return (loc); | |||
| 1084 | } | |||
| 1085 | ||||
| 1086 | /* | |||
| 1087 | * Disassemble instruction at 'loc'. 'altfmt' specifies an | |||
| 1088 | * (optional) alternate format. Return address of start of | |||
| 1089 | * next instruction. | |||
| 1090 | */ | |||
| 1091 | vaddr_t | |||
| 1092 | db_disasm(vaddr_t loc, int altfmt) | |||
| 1093 | { | |||
| 1094 | int inst; | |||
| 1095 | int size; | |||
| 1096 | int short_addr; | |||
| 1097 | char * seg; | |||
| 1098 | struct inst * ip; | |||
| 1099 | char * i_name; | |||
| 1100 | int i_size; | |||
| 1101 | int i_mode; | |||
| 1102 | int regmodrm = 0; | |||
| 1103 | int first; | |||
| 1104 | int displ; | |||
| 1105 | int prefix; | |||
| 1106 | long imm; | |||
| 1107 | int imm2; | |||
| 1108 | int len; | |||
| 1109 | int rex = 0; | |||
| 1110 | int segovr_grp; | |||
| 1111 | int repe, repne; | |||
| 1112 | struct i_addr address; | |||
| 1113 | vaddr_t loc_orig = loc; | |||
| 1114 | char tmpfmt[28]; | |||
| 1115 | ||||
| 1116 | get_value_inc(inst, loc, 1, 0)do { inst = db_get_value((loc), (1), (0)); (loc) += (1); } while (0); | |||
| ||||
| 1117 | short_addr = 0; | |||
| 1118 | size = LONG2; | |||
| 1119 | seg = 0; | |||
| 1120 | segovr_grp = 0; | |||
| 1121 | repe = 0; | |||
| 1122 | repne = 0; | |||
| 1123 | ||||
| 1124 | /* | |||
| 1125 | * Get prefixes | |||
| 1126 | */ | |||
| 1127 | prefix = 1; | |||
| 1128 | do { | |||
| 1129 | switch (inst) { | |||
| 1130 | case 0x66: /* data16 */ | |||
| 1131 | size = WORD1; | |||
| 1132 | break; | |||
| 1133 | case 0x67: | |||
| 1134 | short_addr = 1; | |||
| 1135 | break; | |||
| 1136 | case 0x26: | |||
| 1137 | segovr_grp++; | |||
| 1138 | db_printf(" <segment override prefix ignored>"); | |||
| 1139 | break; | |||
| 1140 | case 0x36: | |||
| 1141 | db_printf(" <segment override prefix ignored>"); | |||
| 1142 | segovr_grp++; | |||
| 1143 | break; | |||
| 1144 | case 0x2e: | |||
| 1145 | db_printf(" <segment override prefix ignored>"); | |||
| 1146 | segovr_grp++; | |||
| 1147 | break; | |||
| 1148 | case 0x3e: | |||
| 1149 | db_printf(" <segment override prefix ignored>"); | |||
| 1150 | segovr_grp++; | |||
| 1151 | break; | |||
| 1152 | case 0x64: | |||
| 1153 | segovr_grp++; | |||
| 1154 | seg = "%fs"; | |||
| 1155 | break; | |||
| 1156 | case 0x65: | |||
| 1157 | segovr_grp++; | |||
| 1158 | seg = "%gs"; | |||
| 1159 | break; | |||
| 1160 | case 0xf0: | |||
| 1161 | db_printf("lock "); | |||
| 1162 | break; | |||
| 1163 | case 0xf2: | |||
| 1164 | repne++; | |||
| 1165 | break; | |||
| 1166 | case 0xf3: | |||
| 1167 | repe++; | |||
| 1168 | break; | |||
| 1169 | default: | |||
| 1170 | prefix = 0; | |||
| 1171 | break; | |||
| 1172 | } | |||
| 1173 | if (prefix
| |||
| 1174 | get_value_inc(inst, loc, 1, 0)do { inst = db_get_value((loc), (1), (0)); (loc) += (1); } while (0); | |||
| 1175 | } while (prefix); | |||
| 1176 | if (segovr_grp
| |||
| 1177 | seg = "<bad segment override prefix combination> "; | |||
| 1178 | if (repe
| |||
| 1179 | db_printf("<bad repeat prefix combination> "); | |||
| 1180 | else if (repe
| |||
| 1181 | db_printf("repe "); /* XXX "rep" if not CMPSx or SCASx */ | |||
| 1182 | else if (repne
| |||
| 1183 | db_printf("repne "); | |||
| 1184 | ||||
| 1185 | if (inst >= 0x40 && inst <= 0x4f) { | |||
| 1186 | // rex page 14 | |||
| 1187 | rex = inst; | |||
| 1188 | if (REX_W(rex)(((rex) & 0x8) == 0x8)) | |||
| 1189 | size = QUAD3; | |||
| 1190 | get_value_inc(inst, loc, 1, 0)do { inst = db_get_value((loc), (1), (0)); (loc) += (1); } while (0); | |||
| 1191 | } | |||
| 1192 | ||||
| 1193 | if (inst
| |||
| 1194 | loc = db_disasm_esc(loc, inst, short_addr, size, rex, seg); | |||
| 1195 | goto done; | |||
| 1196 | } | |||
| 1197 | ||||
| 1198 | if (inst == 0x0f) { | |||
| 1199 | get_value_inc(inst, loc, 1, 0)do { inst = db_get_value((loc), (1), (0)); (loc) += (1); } while (0); | |||
| 1200 | if (inst == 0x0f) { | |||
| 1201 | loc = db_disasm_3dnow(loc, short_addr, size, rex, seg); | |||
| 1202 | goto done; | |||
| 1203 | } | |||
| 1204 | ip = db_inst_0f[inst>>4]; | |||
| 1205 | if (ip == 0) | |||
| 1206 | ip = &db_bad_inst; | |||
| 1207 | else | |||
| 1208 | ip = &ip[inst&0xf]; | |||
| 1209 | } else { | |||
| 1210 | ip = &db_inst_table[inst]; | |||
| 1211 | } | |||
| 1212 | ||||
| 1213 | if (ip->i_has_modrm) { | |||
| 1214 | get_value_inc(regmodrm, loc, 1, 0)do { regmodrm = db_get_value((loc), (1), (0)); (loc) += (1); } while (0); | |||
| 1215 | loc = db_read_address(loc, short_addr, regmodrm, rex, &address); | |||
| 1216 | } | |||
| 1217 | ||||
| 1218 | i_name = ip->i_name; | |||
| 1219 | i_size = ip->i_size; | |||
| 1220 | i_mode = ip->i_mode; | |||
| 1221 | ||||
| 1222 | if (i_size == RDEP9) { | |||
| 1223 | /* sub-table to handle dependency on reg from ModR/M byte */ | |||
| 1224 | ip = (struct inst *)ip->i_extra; | |||
| 1225 | ip = &ip[f_reg(regmodrm, 0)((((regmodrm)>>3)&0x7) + (((0) & 0x4) << 1 ))]; | |||
| 1226 | i_name = ip->i_name; | |||
| 1227 | i_mode = ip->i_mode; | |||
| 1228 | i_size = ip->i_size; | |||
| 1229 | } else if (i_name == NULL((void *)0)) { | |||
| 1230 | i_name = ((char **)ip->i_extra)[f_reg(regmodrm, 0)((((regmodrm)>>3)&0x7) + (((0) & 0x4) << 1 ))]; | |||
| 1231 | } else if (ip->i_extra == db_Grp3) { | |||
| 1232 | ip = (struct inst *)ip->i_extra; | |||
| 1233 | ip = &ip[f_reg(regmodrm, 0)((((regmodrm)>>3)&0x7) + (((0) & 0x4) << 1 ))]; | |||
| 1234 | i_name = ip->i_name; | |||
| 1235 | i_mode = ip->i_mode; | |||
| 1236 | } | |||
| 1237 | ||||
| 1238 | /* ModR/M-specific operation? */ | |||
| 1239 | if ((i_mode & 0xFF) == MEx38) { | |||
| 1240 | if (f_mod(regmodrm)((regmodrm)>>6) != 3) | |||
| 1241 | i_mode = op1(E)(1); | |||
| 1242 | else { | |||
| 1243 | /* unknown extension? */ | |||
| 1244 | if (f_rm(regmodrm, 0)(((regmodrm)&0x7) + (((0) & 0x1) << 3)) > (i_mode >> 8)) | |||
| 1245 | i_name = ""; | |||
| 1246 | else { | |||
| 1247 | /* skip to the specific op */ | |||
| 1248 | int i = f_rm(regmodrm, 0)(((regmodrm)&0x7) + (((0) & 0x1) << 3)); | |||
| 1249 | i_name = ip->i_extra; | |||
| 1250 | while (i-- > 0) | |||
| 1251 | while (*i_name++) | |||
| 1252 | ; | |||
| 1253 | } | |||
| 1254 | i_mode = 0; | |||
| 1255 | } | |||
| 1256 | } | |||
| 1257 | ||||
| 1258 | if (i_size == SDEP7) { | |||
| 1259 | if (size == WORD1) | |||
| 1260 | db_printf("%s", i_name); | |||
| 1261 | else if (size == LONG2) | |||
| 1262 | db_printf("%s", (char *)ip->i_extra); | |||
| 1263 | else { | |||
| 1264 | char *cp = ip->i_extra; | |||
| 1265 | while (*cp) | |||
| 1266 | cp++; | |||
| 1267 | cp++; | |||
| 1268 | db_printf("%s", cp); | |||
| 1269 | } | |||
| 1270 | } else { | |||
| 1271 | db_printf("%s", i_name); | |||
| 1272 | if (i_size != NONE8) { | |||
| 1273 | if (i_size == BYTE0) { | |||
| 1274 | db_printf("b"); | |||
| 1275 | size = BYTE0; | |||
| 1276 | } else if (REX_W(rex)(((rex) & 0x8) == 0x8)) { | |||
| 1277 | db_printf("q"); | |||
| 1278 | size = QUAD3; | |||
| 1279 | } else if (i_size == WORD1) { | |||
| 1280 | db_printf("w"); | |||
| 1281 | size = WORD1; | |||
| 1282 | } else if (i_size == QUAD3) { | |||
| 1283 | size = QUAD3; | |||
| 1284 | db_printf("q"); | |||
| 1285 | } else if (size == WORD1) { | |||
| 1286 | db_printf("w"); | |||
| 1287 | } else { | |||
| 1288 | db_printf("l"); | |||
| 1289 | } | |||
| 1290 | } | |||
| 1291 | } | |||
| 1292 | db_printf("\t"); | |||
| 1293 | for (first = 1; i_mode != 0; i_mode >>= 8, first = 0) { | |||
| 1294 | if (!first
| |||
| 1295 | db_printf(","); | |||
| 1296 | ||||
| 1297 | switch (i_mode & 0xFF) { | |||
| 1298 | case E1: //XXX | |||
| 1299 | db_print_address(seg, size, &address); | |||
| 1300 | break; | |||
| 1301 | case Eind2: //XXX | |||
| 1302 | db_printf("*"); | |||
| 1303 | db_print_address(seg, size, &address); | |||
| 1304 | break; | |||
| 1305 | case Ew3: //XXX | |||
| 1306 | db_print_address(seg, WORD1, &address); | |||
| 1307 | break; | |||
| 1308 | case Eb4: //XXX | |||
| 1309 | db_print_address(seg, BYTE0, &address); | |||
| 1310 | break; | |||
| 1311 | case R5: | |||
| 1312 | db_printf("%s", db_reg[size][f_reg(regmodrm, rex)((((regmodrm)>>3)&0x7) + (((rex) & 0x4) << 1))]); | |||
| 1313 | break; | |||
| 1314 | case Rw6: | |||
| 1315 | db_printf("%s", db_reg[WORD1][f_reg(regmodrm, rex)((((regmodrm)>>3)&0x7) + (((rex) & 0x4) << 1))]); | |||
| 1316 | break; | |||
| 1317 | case Ri7: | |||
| 1318 | db_printf("%s", db_reg[size][f_rm(inst, rex)(((inst)&0x7) + (((rex) & 0x1) << 3))]); | |||
| 1319 | break; | |||
| 1320 | case Ril36: | |||
| 1321 | db_printf("%s", db_reg[LONG2][f_rm(inst, rex)(((inst)&0x7) + (((rex) & 0x1) << 3))]); | |||
| 1322 | break; | |||
| 1323 | case S8: | |||
| 1324 | db_printf("%s", db_seg_reg[f_reg(regmodrm, 0)((((regmodrm)>>3)&0x7) + (((0) & 0x4) << 1 ))]); | |||
| 1325 | break; | |||
| 1326 | case Si9: | |||
| 1327 | db_printf("%s", db_seg_reg[f_reg(inst, 0)((((inst)>>3)&0x7) + (((0) & 0x4) << 1))]); | |||
| 1328 | break; | |||
| 1329 | case A10: | |||
| 1330 | db_printf("%s", db_reg[size][0]); /* acc */ | |||
| 1331 | break; | |||
| 1332 | case BX11: | |||
| 1333 | if (seg) | |||
| 1334 | db_printf("%s:", seg); | |||
| 1335 | db_printf("(%s)", short_addr ? "%ebx" : "%rbx"); | |||
| 1336 | break; | |||
| 1337 | case CL12: | |||
| 1338 | db_printf("%%cl"); | |||
| 1339 | break; | |||
| 1340 | case DX13: | |||
| 1341 | db_printf("%%dx"); | |||
| 1342 | break; | |||
| 1343 | case SI14: | |||
| 1344 | if (seg) | |||
| 1345 | db_printf("%s:", seg); | |||
| 1346 | db_printf("(%s)", short_addr ? "%esi" : "%rsi"); | |||
| 1347 | break; | |||
| 1348 | case DI15: | |||
| 1349 | db_printf("%%es:(%s)", short_addr ? "%edi" : "%rdi"); | |||
| 1350 | break; | |||
| 1351 | case CR16: | |||
| 1352 | db_printf("%%cr%d", f_reg(regmodrm, rex)((((regmodrm)>>3)&0x7) + (((rex) & 0x4) << 1))); | |||
| 1353 | break; | |||
| 1354 | case DR17: | |||
| 1355 | db_printf("%%dr%d", f_reg(regmodrm, rex)((((regmodrm)>>3)&0x7) + (((rex) & 0x4) << 1))); | |||
| 1356 | break; | |||
| 1357 | case TR18: //XXX | |||
| 1358 | db_printf("%%tr%d", f_reg(regmodrm, rex)((((regmodrm)>>3)&0x7) + (((rex) & 0x4) << 1))); | |||
| 1359 | break; | |||
| 1360 | case I19: | |||
| 1361 | len = db_lengths[size]; | |||
| 1362 | get_value_inc(imm, loc, len, 0)do { imm = db_get_value((loc), (len), (0)); (loc) += (len); } while (0); | |||
| 1363 | db_printf("$%s", db_format(tmpfmt, sizeof tmpfmt, | |||
| 1364 | (int)imm, DB_FORMAT_N3, 1, 0)); | |||
| 1365 | break; | |||
| 1366 | case Is20: | |||
| 1367 | len = db_lengths[size]; | |||
| 1368 | get_value_inc(imm, loc, len, 1)do { imm = db_get_value((loc), (len), (1)); (loc) += (len); } while (0); | |||
| 1369 | db_printf("$%s", db_format(tmpfmt, sizeof tmpfmt, | |||
| 1370 | (int)imm, DB_FORMAT_R2, 1, 0)); | |||
| 1371 | break; | |||
| 1372 | case Ib21: | |||
| 1373 | get_value_inc(imm, loc, 1, 0)do { imm = db_get_value((loc), (1), (0)); (loc) += (1); } while (0); | |||
| 1374 | db_printf("$%s", db_format(tmpfmt, sizeof tmpfmt, | |||
| 1375 | (int)imm, DB_FORMAT_N3, 1, 0)); | |||
| 1376 | break; | |||
| 1377 | case Iba37: | |||
| 1378 | get_value_inc(imm, loc, 1, 0)do { imm = db_get_value((loc), (1), (0)); (loc) += (1); } while (0); | |||
| 1379 | if (imm != 0x0a) | |||
| 1380 | db_printf("$%s", db_format(tmpfmt, sizeof tmpfmt, | |||
| 1381 | (int)imm, DB_FORMAT_N3, 1, 0)); | |||
| 1382 | break; | |||
| 1383 | case Ibs22: //XXX | |||
| 1384 | get_value_inc(imm, loc, 1, 1)do { imm = db_get_value((loc), (1), (1)); (loc) += (1); } while (0); | |||
| 1385 | if (size == WORD1) | |||
| 1386 | imm &= 0xFFFF; | |||
| 1387 | db_printf("$%s", db_format(tmpfmt, sizeof tmpfmt, | |||
| 1388 | (int)imm, DB_FORMAT_R2, 1, 0)); | |||
| 1389 | break; | |||
| 1390 | case Iw23: | |||
| 1391 | get_value_inc(imm, loc, 2, 0)do { imm = db_get_value((loc), (2), (0)); (loc) += (2); } while (0); | |||
| 1392 | db_printf("$%s", db_format(tmpfmt, sizeof tmpfmt, | |||
| 1393 | (int)imm, DB_FORMAT_N3, 1, 0)); | |||
| 1394 | break; | |||
| 1395 | case Iq24: | |||
| 1396 | get_value_inc(imm, loc, 8, 1)do { imm = db_get_value((loc), (8), (1)); (loc) += (8); } while (0); | |||
| 1397 | db_printf("$%s", db_format(tmpfmt, sizeof tmpfmt, | |||
| 1398 | (int)((imm >> 32) & 0xffffffff), DB_FORMAT_R2, 1, 0)); | |||
| 1399 | db_printf(" %s", db_format(tmpfmt, sizeof tmpfmt, | |||
| 1400 | (int)(imm & 0xffffffff), DB_FORMAT_R2, 1, 0)); | |||
| 1401 | break; | |||
| 1402 | case O25: //XXX | |||
| 1403 | if (short_addr) | |||
| 1404 | get_value_inc(displ, loc, 2, 1)do { displ = db_get_value((loc), (2), (1)); (loc) += (2); } while (0); | |||
| 1405 | else | |||
| 1406 | get_value_inc(displ, loc, 4, 1)do { displ = db_get_value((loc), (4), (1)); (loc) += (4); } while (0); | |||
| 1407 | if (seg) | |||
| 1408 | db_printf("%s:%s", seg, db_format(tmpfmt, | |||
| 1409 | sizeof tmpfmt, displ, DB_FORMAT_R2, 1, 0)); | |||
| 1410 | else | |||
| 1411 | db_printsym((vaddr_t)displ, DB_STGY_ANY0, | |||
| 1412 | db_printf); | |||
| 1413 | break; | |||
| 1414 | case Db26: //XXX | |||
| 1415 | get_value_inc(displ, loc, 1, 1)do { displ = db_get_value((loc), (1), (1)); (loc) += (1); } while (0); | |||
| 1416 | displ += loc; | |||
| 1417 | if (size == WORD1) | |||
| 1418 | displ &= 0xFFFF; | |||
| 1419 | db_printsym((vaddr_t)displ, DB_STGY_XTRN1, db_printf); | |||
| 1420 | break; | |||
| 1421 | case Dl27: //XXX | |||
| 1422 | len = db_lengths[size]; | |||
| 1423 | get_value_inc(displ, loc, len, 0)do { displ = db_get_value((loc), (len), (0)); (loc) += (len); } while (0); | |||
| 1424 | displ += loc; | |||
| 1425 | if (size == WORD1) | |||
| 1426 | displ &= 0xFFFF; | |||
| 1427 | db_printsym((vaddr_t)displ, DB_STGY_XTRN1, db_printf); | |||
| 1428 | break; | |||
| 1429 | case o128: //XXX | |||
| 1430 | db_printf("$1"); | |||
| 1431 | break; | |||
| 1432 | case o329: //XXX | |||
| 1433 | db_printf("$3"); | |||
| 1434 | break; | |||
| 1435 | case OS30: //XXX | |||
| 1436 | len = db_lengths[size]; | |||
| 1437 | get_value_inc(imm, loc, len, 0)do { imm = db_get_value((loc), (len), (0)); (loc) += (len); } while (0); /* offset */ | |||
| 1438 | get_value_inc(imm2, loc, 2, 0)do { imm2 = db_get_value((loc), (2), (0)); (loc) += (2); } while (0); /* segment */ | |||
| 1439 | db_printf("$0x%#x", imm2); | |||
| 1440 | break; | |||
| 1441 | } | |||
| 1442 | } | |||
| 1443 | ||||
| 1444 | if (altfmt == 0 && (inst == 0xe9 || inst == 0xeb)) { | |||
| 1445 | /* | |||
| 1446 | * GAS pads to longword boundary after unconditional jumps. | |||
| 1447 | */ | |||
| 1448 | loc = (loc + (4-1)) & ~(4-1); | |||
| 1449 | } | |||
| 1450 | done: | |||
| 1451 | if (loc - loc_orig > 15) | |||
| 1452 | db_printf(" <instruction too long>"); | |||
| 1453 | if (altfmt) { | |||
| 1454 | db_printf("\n\t"); | |||
| 1455 | while (loc_orig < loc) { | |||
| 1456 | get_value_inc(imm, loc_orig, 1, 0)do { imm = db_get_value((loc_orig), (1), (0)); (loc_orig) += ( 1); } while (0); | |||
| 1457 | if (imm < 0x10) | |||
| 1458 | db_printf("0"); | |||
| 1459 | db_printf("%x ", (int)imm); | |||
| 1460 | } | |||
| 1461 | } | |||
| 1462 | db_printf("\n"); | |||
| 1463 | return (loc); | |||
| 1464 | } |