|
|
1.1 ! root 1: /* i386.h -- Header file for i386.c ! 2: Copyright (C) 1989, Free Software Foundation. ! 3: ! 4: This file is part of GAS, the GNU Assembler. ! 5: ! 6: GAS is free software; you can redistribute it and/or modify ! 7: it under the terms of the GNU General Public License as published by ! 8: the Free Software Foundation; either version 1, or (at your option) ! 9: any later version. ! 10: ! 11: GAS is distributed in the hope that it will be useful, ! 12: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 14: GNU General Public License for more details. ! 15: ! 16: You should have received a copy of the GNU General Public License ! 17: along with GAS; see the file COPYING. If not, write to ! 18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ! 19: ! 20: #define MAX_OPERANDS 3 /* max operands per insn */ ! 21: #define MAX_PREFIXES 4 /* max prefixes per opcode */ ! 22: #define MAX_IMMEDIATE_OPERANDS 2 /* max immediates per insn */ ! 23: #define MAX_MEMORY_OPERANDS 2 /* max memory ref per insn ! 24: * lcall uses 2 ! 25: */ ! 26: /* we define the syntax here (modulo base,index,scale syntax) */ ! 27: #define REGISTER_PREFIX '%' ! 28: #define IMMEDIATE_PREFIX '$' ! 29: #define ABSOLUTE_PREFIX '*' ! 30: #define PREFIX_SEPERATOR '/' ! 31: ! 32: #define TWO_BYTE_OPCODE_ESCAPE 0x0f ! 33: ! 34: /* register numbers */ ! 35: #define EBP_REG_NUM 5 ! 36: #define ESP_REG_NUM 4 ! 37: ! 38: /* modrm_byte.regmem for twobyte escape */ ! 39: #define ESCAPE_TO_TWO_BYTE_ADDRESSING ESP_REG_NUM ! 40: /* index_base_byte.index for no index register addressing */ ! 41: #define NO_INDEX_REGISTER ESP_REG_NUM ! 42: /* index_base_byte.base for no base register addressing */ ! 43: #define NO_BASE_REGISTER EBP_REG_NUM ! 44: ! 45: /* these are the att as opcode suffixes, making movl --> mov, for example */ ! 46: #define DWORD_OPCODE_SUFFIX 'l' ! 47: #define WORD_OPCODE_SUFFIX 'w' ! 48: #define BYTE_OPCODE_SUFFIX 'b' ! 49: ! 50: /* modrm.mode = REGMEM_FIELD_HAS_REG when a register is in there */ ! 51: #define REGMEM_FIELD_HAS_REG 0x3 /* always = 0x3 */ ! 52: #define REGMEM_FIELD_HAS_MEM (~REGMEM_FIELD_HAS_REG) ! 53: ! 54: #define END_OF_INSN '\0' ! 55: ! 56: /* ! 57: When an operand is read in it is classified by its type. This type includes ! 58: all the possible ways an operand can be used. Thus, '%eax' is both 'register ! 59: # 0' and 'The Accumulator'. In our language this is expressed by OR'ing ! 60: 'Reg32' (any 32 bit register) and 'Acc' (the accumulator). ! 61: Operands are classified so that we can match given operand types with ! 62: the opcode table in i386-opcode.h. ! 63: */ ! 64: #define Unknown 0x0 ! 65: /* register */ ! 66: #define Reg8 0x1 /* 8 bit reg */ ! 67: #define Reg16 0x2 /* 16 bit reg */ ! 68: #define Reg32 0x4 /* 32 bit reg */ ! 69: #define Reg (Reg8|Reg16|Reg32) /* gen'l register */ ! 70: #define WordReg (Reg16|Reg32) /* for push/pop operands */ ! 71: /* immediate */ ! 72: #define Imm8 0x8 /* 8 bit immediate */ ! 73: #define Imm8S 0x10 /* 8 bit immediate sign extended */ ! 74: #define Imm16 0x20 /* 16 bit immediate */ ! 75: #define Imm32 0x40 /* 32 bit immediate */ ! 76: #define Imm1 0x80 /* 1 bit immediate */ ! 77: #define ImmUnknown Imm32 /* for unknown expressions */ ! 78: #define Imm (Imm8|Imm8S|Imm16|Imm32) /* gen'l immediate */ ! 79: /* memory */ ! 80: #define Disp8 0x200 /* 8 bit displacement (for jumps) */ ! 81: #define Disp16 0x400 /* 16 bit displacement */ ! 82: #define Disp32 0x800 /* 32 bit displacement */ ! 83: #define Disp (Disp8|Disp16|Disp32) /* General displacement */ ! 84: #define DispUnknown Disp32 /* for unknown size displacements */ ! 85: #define Mem8 0x1000 ! 86: #define Mem16 0x2000 ! 87: #define Mem32 0x4000 ! 88: #define BaseIndex 0x8000 ! 89: #define Mem (Disp|Mem8|Mem16|Mem32|BaseIndex) /* General memory */ ! 90: #define WordMem (Mem16|Mem32|Disp|BaseIndex) ! 91: #define ByteMem (Mem8|Disp|BaseIndex) ! 92: /* specials */ ! 93: #define InOutPortReg 0x10000 /* register to hold in/out port addr = dx */ ! 94: #define ShiftCount 0x20000 /* register to hold shift cound = cl */ ! 95: #define Control 0x40000 /* Control register */ ! 96: #define Debug 0x80000 /* Debug register */ ! 97: #define Test 0x100000 /* Test register */ ! 98: #define FloatReg 0x200000 /* Float register */ ! 99: #define FloatAcc 0x400000 /* Float stack top %st(0) */ ! 100: #define SReg2 0x800000 /* 2 bit segment register */ ! 101: #define SReg3 0x1000000 /* 3 bit segment register */ ! 102: #define Acc 0x2000000 /* Accumulator %al or %ax or %eax */ ! 103: #define ImplicitRegister (InOutPortReg|ShiftCount|Acc|FloatAcc) ! 104: #define JumpAbsolute 0x4000000 ! 105: #define Abs8 0x08000000 ! 106: #define Abs16 0x10000000 ! 107: #define Abs32 0x20000000 ! 108: #define Abs (Abs8|Abs16|Abs32) ! 109: ! 110: #define MODE_FROM_DISP_SIZE(t) \ ! 111: ((t&(Disp8)) ? 1 : \ ! 112: ((t&(Disp32)) ? 2 : 0)) ! 113: ! 114: #define Byte (Reg8|Imm8|Imm8S) ! 115: #define Word (Reg16|Imm16) ! 116: #define DWord (Reg32|Imm32) ! 117: ! 118: /* convert opcode suffix ('b' 'w' 'l' typically) into type specifyer */ ! 119: #define OPCODE_SUFFIX_TO_TYPE(s) \ ! 120: (s == BYTE_OPCODE_SUFFIX ? Byte : \ ! 121: (s == WORD_OPCODE_SUFFIX ? Word : DWord)) ! 122: ! 123: #define FITS_IN_SIGNED_BYTE(num) ((num) >= -128 && (num) <= 127) ! 124: #define FITS_IN_UNSIGNED_BYTE(num) ((num) >= 0 && (num) <= 255) ! 125: #define FITS_IN_UNSIGNED_WORD(num) ((num) >= 0 && (num) <= 65535) ! 126: #define FITS_IN_SIGNED_WORD(num) ((num) >= -32768 && (num) <= 32767) ! 127: ! 128: #define SMALLEST_DISP_TYPE(num) \ ! 129: FITS_IN_SIGNED_BYTE(num) ? (Disp8|Disp32|Abs8|Abs32) : (Disp32|Abs32) ! 130: ! 131: #define SMALLEST_IMM_TYPE(num) \ ! 132: (num == 1) ? (Imm1|Imm8|Imm8S|Imm16|Imm32): \ ! 133: FITS_IN_SIGNED_BYTE(num) ? (Imm8S|Imm8|Imm16|Imm32) : \ ! 134: FITS_IN_UNSIGNED_BYTE(num) ? (Imm8|Imm16|Imm32): \ ! 135: (FITS_IN_SIGNED_WORD(num)||FITS_IN_UNSIGNED_WORD(num)) ? (Imm16|Imm32) : \ ! 136: (Imm32) ! 137: ! 138: typedef unsigned char uchar; ! 139: typedef unsigned int uint; ! 140: ! 141: typedef struct { ! 142: /* instruction name sans width suffix ("mov" for movl insns) */ ! 143: char *name; ! 144: ! 145: /* how many operands */ ! 146: uint operands; ! 147: ! 148: /* base_opcode is the fundamental opcode byte with a optional prefix(es). */ ! 149: uint base_opcode; ! 150: ! 151: /* extension_opcode is the 3 bit extension for group <n> insns. ! 152: If this template has no extension opcode (the usual case) use None */ ! 153: uchar extension_opcode; ! 154: #define None 0xff /* If no extension_opcode is possible. */ ! 155: ! 156: /* the bits in opcode_modifier are used to generate the final opcode from ! 157: the base_opcode. These bits also are used to detect alternate forms of ! 158: the same instruction */ ! 159: uint opcode_modifier; ! 160: ! 161: /* opcode_modifier bits: */ ! 162: #define W 0x1 /* set if operands are words or dwords */ ! 163: #define D 0x2 /* D = 0 if Reg --> Regmem; D = 1 if Regmem --> Reg */ ! 164: /* direction flag for floating insns: MUST BE 0x400 */ ! 165: #define FloatD 0x400 ! 166: /* shorthand */ ! 167: #define DW (D|W) ! 168: #define ShortForm 0x10 /* register is in low 3 bits of opcode */ ! 169: #define ShortFormW 0x20 /* ShortForm and W bit is 0x8 */ ! 170: #define Seg2ShortForm 0x40 /* encoding of load segment reg insns */ ! 171: #define Seg3ShortForm 0x80 /* fs/gs segment register insns. */ ! 172: #define Jump 0x100 /* special case for jump insns. */ ! 173: #define JumpInterSegment 0x200 /* special case for intersegment leaps/calls */ ! 174: /* 0x400 CANNOT BE USED since it's already used by FloatD above */ ! 175: #define DONT_USE 0x400 ! 176: #define NoModrm 0x800 ! 177: #define Modrm 0x1000 ! 178: #define imulKludge 0x2000 ! 179: #define JumpByte 0x4000 ! 180: #define JumpDword 0x8000 ! 181: #define ReverseRegRegmem 0x10000 ! 182: ! 183: /* (opcode_modifier & COMES_IN_ALL_SIZES) is true if the ! 184: instuction comes in byte, word, and dword sizes and is encoded into ! 185: machine code in the canonical way. */ ! 186: #define COMES_IN_ALL_SIZES (W) ! 187: ! 188: /* (opcode_modifier & COMES_IN_BOTH_DIRECTIONS) indicates that the ! 189: source and destination operands can be reversed by setting either ! 190: the D (for integer insns) or the FloatD (for floating insns) bit ! 191: in base_opcode. */ ! 192: #define COMES_IN_BOTH_DIRECTIONS (D|FloatD) ! 193: ! 194: /* operand_types[i] describes the type of operand i. This is made ! 195: by OR'ing together all of the possible type masks. (e.g. ! 196: 'operand_types[i] = Reg|Imm' specifies that operand i can be ! 197: either a register or an immediate operand */ ! 198: uint operand_types[3]; ! 199: } template; ! 200: ! 201: /* ! 202: 'templates' is for grouping together 'template' structures for opcodes ! 203: of the same name. This is only used for storing the insns in the grand ! 204: ole hash table of insns. ! 205: The templates themselves start at START and range up to (but not including) ! 206: END. ! 207: */ ! 208: typedef struct { ! 209: template *start; ! 210: template *end; ! 211: } templates; ! 212: ! 213: /* these are for register name --> number & type hash lookup */ ! 214: typedef struct { ! 215: char * reg_name; ! 216: uint reg_type; ! 217: uint reg_num; ! 218: } reg_entry; ! 219: ! 220: typedef struct { ! 221: char * seg_name; ! 222: uint seg_prefix; ! 223: } seg_entry; ! 224: ! 225: /* these are for prefix name --> prefix code hash lookup */ ! 226: typedef struct { ! 227: char * prefix_name; ! 228: uchar prefix_code; ! 229: } prefix_entry; ! 230: ! 231: /* 386 operand encoding bytes: see 386 book for details of this. */ ! 232: typedef struct { ! 233: unsigned regmem:3; /* codes register or memory operand */ ! 234: unsigned reg:3; /* codes register operand (or extended opcode) */ ! 235: unsigned mode:2; /* how to interpret regmem & reg */ ! 236: } modrm_byte; ! 237: ! 238: /* 386 opcode byte to code indirect addressing. */ ! 239: typedef struct { ! 240: unsigned base:3; ! 241: unsigned index:3; ! 242: unsigned scale:2; ! 243: } base_index_byte; ! 244: ! 245: /* 'md_assemble ()' gathers together information and puts it into a ! 246: i386_insn. */ ! 247: ! 248: typedef struct { ! 249: /* TM holds the template for the insn were currently assembling. */ ! 250: template tm; ! 251: /* SUFFIX holds the opcode suffix (e.g. 'l' for 'movl') if given. */ ! 252: char suffix; ! 253: /* Operands are coded with OPERANDS, TYPES, DISPS, IMMS, and REGS. */ ! 254: ! 255: /* OPERANDS gives the number of given operands. */ ! 256: uint operands; ! 257: ! 258: /* REG_OPERANDS, DISP_OPERANDS, MEM_OPERANDS, IMM_OPERANDS give the number of ! 259: given register, displacement, memory operands and immediate operands. */ ! 260: uint reg_operands, disp_operands, mem_operands, imm_operands; ! 261: ! 262: /* TYPES [i] is the type (see above #defines) which tells us how to ! 263: search through DISPS [i] & IMMS [i] & REGS [i] for the required ! 264: operand. */ ! 265: uint types [MAX_OPERANDS]; ! 266: ! 267: /* Displacements (if given) for each operand. */ ! 268: expressionS * disps [MAX_OPERANDS]; ! 269: ! 270: /* Immediate operands (if given) for each operand. */ ! 271: expressionS * imms [MAX_OPERANDS]; ! 272: ! 273: /* Register operands (if given) for each operand. */ ! 274: reg_entry * regs [MAX_OPERANDS]; ! 275: ! 276: /* BASE_REG, INDEX_REG, and LOG2_SCALE_FACTOR are used to encode ! 277: the base index byte below. */ ! 278: reg_entry * base_reg; ! 279: reg_entry * index_reg; ! 280: uint log2_scale_factor; ! 281: ! 282: /* SEG gives the seg_entry of this insn. It is equal to zero unless ! 283: an explicit segment override is given. */ ! 284: seg_entry * seg; /* segment for memory operands (if given) */ ! 285: ! 286: /* PREFIX holds all the given prefix opcodes (usually null). ! 287: PREFIXES is the size of PREFIX. */ ! 288: char prefix [MAX_PREFIXES]; ! 289: uint prefixes; ! 290: ! 291: /* RM and IB are the modrm byte and the base index byte where the addressing ! 292: modes of this insn are encoded. */ ! 293: ! 294: modrm_byte rm; ! 295: base_index_byte bi; ! 296: } i386_insn;
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.