i386base.pas 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979
  1. {
  2. $Id$
  3. Copyright (c) 1999 by Florian Klaempfl
  4. Contains the base types for the i386
  5. * This code was inspired by the NASM sources
  6. The Netwide Assembler is copyright (C) 1996 Simon Tatham and
  7. Julian Hall. All rights reserved.
  8. This program is free software; you can redistribute it and/or modify
  9. it under the terms of the GNU General Public License as published by
  10. the Free Software Foundation; either version 2 of the License, or
  11. (at your option) any later version.
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. GNU General Public License for more details.
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19. ****************************************************************************
  20. }
  21. unit i386base;
  22. interface
  23. {$ifdef TP}
  24. {$L-,Y-}
  25. {$endif}
  26. uses
  27. strings,cobjects,aasm;
  28. const
  29. { Size of the instruction table converted by nasmconv.pas }
  30. instabentries = 1103;
  31. maxinfolen = 7;
  32. { By default we want everything }
  33. {$define ATTOP}
  34. {$define ATTREG}
  35. {$define INTELOP}
  36. {$define ITTABLE}
  37. { For TP we can't use asmdebug due the table sizes }
  38. {$ifndef TP}
  39. {$define ASMDEBUG}
  40. {$endif}
  41. { We Don't need the intel style opcodes if we don't have a intel
  42. reader or generator }
  43. {$ifndef ASMDEBUG}
  44. {$ifdef NORA386INT}
  45. {$ifdef NOAG386NSM}
  46. {$ifdef NOAG386INT}
  47. {$undef INTELOP}
  48. {$endif}
  49. {$endif}
  50. {$endif}
  51. {$endif}
  52. { We Don't need the AT&T style opcodes if we don't have a AT&T
  53. reader or generator }
  54. {$ifdef NORA386ATT}
  55. {$ifdef NOAG386ATT}
  56. {$undef ATTOP}
  57. {$ifdef NOAG386DIR}
  58. {$undef ATTREG}
  59. {$endif}
  60. {$endif}
  61. {$endif}
  62. const
  63. { Operand types }
  64. OT_NONE = $00000000;
  65. OT_BITS8 = $00000001; { size, and other attributes, of the operand }
  66. OT_BITS16 = $00000002;
  67. OT_BITS32 = $00000004;
  68. OT_BITS64 = $00000008; { FPU only }
  69. OT_BITS80 = $00000010;
  70. OT_FAR = $00000020; { this means 16:16 or 16:32, like in CALL/JMP }
  71. OT_NEAR = $00000040;
  72. OT_SHORT = $00000080;
  73. OT_SIZE_MASK = $000000FF; { all the size attributes }
  74. OT_NON_SIZE = not OT_SIZE_MASK;
  75. OT_SIGNED = $00000100; { the operand need to be signed -128-127 }
  76. OT_TO = $00000200; { operand is followed by a colon }
  77. { reverse effect in FADD, FSUB &c }
  78. OT_COLON = $00000400;
  79. OT_REGISTER = $00001000;
  80. OT_IMMEDIATE = $00002000;
  81. OT_IMM8 = $00002001;
  82. OT_IMM16 = $00002002;
  83. OT_IMM32 = $00002004;
  84. OT_IMM64 = $00002008;
  85. OT_IMM80 = $00002010;
  86. OT_REGMEM = $00200000; { for r/m, ie EA, operands }
  87. OT_REGNORM = $00201000; { 'normal' reg, qualifies as EA }
  88. OT_REG8 = $00201001;
  89. OT_REG16 = $00201002;
  90. OT_REG32 = $00201004;
  91. OT_MMXREG = $00201008; { MMX registers }
  92. OT_MEMORY = $00204000; { register number in 'basereg' }
  93. OT_MEM8 = $00204001;
  94. OT_MEM16 = $00204002;
  95. OT_MEM32 = $00204004;
  96. OT_MEM64 = $00204008;
  97. OT_MEM80 = $00204010;
  98. OT_FPUREG = $01000000; { floating point stack registers }
  99. OT_FPU0 = $01000800; { FPU stack register zero }
  100. OT_REG_SMASK = $00070000; { special register operands: these may be treated differently }
  101. { a mask for the following }
  102. OT_REG_ACCUM = $00211000; { accumulator: AL, AX or EAX }
  103. OT_REG_AL = $00211001; { REG_ACCUM | BITSxx }
  104. OT_REG_AX = $00211002; { ditto }
  105. OT_REG_EAX = $00211004; { and again }
  106. OT_REG_COUNT = $00221000; { counter: CL, CX or ECX }
  107. OT_REG_CL = $00221001; { REG_COUNT | BITSxx }
  108. OT_REG_CX = $00221002; { ditto }
  109. OT_REG_ECX = $00221004; { another one }
  110. OT_REG_DX = $00241002;
  111. OT_REG_SREG = $00081002; { any segment register }
  112. OT_REG_CS = $01081002; { CS }
  113. OT_REG_DESS = $02081002; { DS, ES, SS (non-CS 86 registers) }
  114. OT_REG_FSGS = $04081002; { FS, GS (386 extended registers) }
  115. OT_REG_CDT = $00101004; { CRn, DRn and TRn }
  116. OT_REG_CREG = $08101004; { CRn }
  117. OT_REG_CR4 = $08101404; { CR4 (Pentium only) }
  118. OT_REG_DREG = $10101004; { DRn }
  119. OT_REG_TREG = $20101004; { TRn }
  120. OT_MEM_OFFS = $00604000; { special type of EA }
  121. { simple [address] offset }
  122. OT_ONENESS = $00800000; { special type of immediate operand }
  123. { so UNITY == IMMEDIATE | ONENESS }
  124. OT_UNITY = $00802000; { for shift/rotate instructions }
  125. { Instruction flags }
  126. IF_SM = $0001; { size match first operand }
  127. IF_SM2 = $0002; { size match first two operands }
  128. IF_SB = $0004; { unsized operands can't be non-byte }
  129. IF_SW = $0008; { unsized operands can't be non-word }
  130. IF_SD = $0010; { unsized operands can't be nondword }
  131. IF_8086 = $0000; { 8086 instruction }
  132. IF_186 = $0100; { 186+ instruction }
  133. IF_286 = $0200; { 286+ instruction }
  134. IF_386 = $0300; { 386+ instruction }
  135. IF_486 = $0400; { 486+ instruction }
  136. IF_PENT = $0500; { Pentium instruction }
  137. IF_P6 = $0600; { P6 instruction }
  138. IF_CYRIX = $0800; { Cyrix-specific instruction }
  139. IF_PMASK = $0F00; { the mask for processor types }
  140. IF_PRIV = $1000; { it's a privileged instruction }
  141. IF_UNDOC = $2000; { it's an undocumented instruction }
  142. IF_FPU = $4000; { it's an FPU instruction }
  143. IF_MMX = $8000; { it's an MMX instruction }
  144. { added flags }
  145. IF_PRE = $10000; { it's a prefix instruction }
  146. IF_PASS2 = $20000; { if the instruction can change in a second pass }
  147. type
  148. TAsmOp=(A_None,
  149. { prefixes }
  150. A_LOCK,A_REP,A_REPE,A_REPNE,A_REPNZ,A_REPZ,
  151. A_CS,A_ES,A_DS,A_FS,A_GS,A_SS,
  152. { normal }
  153. A_AAA, A_AAD, A_AAM, A_AAS, A_ADC, A_ADD, A_AND, A_ARPL,
  154. A_BOUND, A_BSF, A_BSR, A_BSWAP, A_BT, A_BTC, A_BTR, A_BTS,
  155. A_CALL, A_CBW, A_CDQ, A_CLC, A_CLD, A_CLI, A_CLTS, A_CMC, A_CMP,
  156. A_CMPSB, A_CMPSD, A_CMPSW, A_CMPXCHG, A_CMPXCHG486, A_CMPXCHG8B,
  157. A_CPUID, A_CWD, A_CWDE, A_DAA, A_DAS, A_DEC, A_DIV,
  158. A_EMMS, A_ENTER, A_EQU, A_F2XM1, A_FABS,
  159. A_FADD, A_FADDP, A_FBLD, A_FBSTP, A_FCHS, A_FCLEX, A_FCMOVB,
  160. A_FCMOVBE, A_FCMOVE, A_FCMOVNB, A_FCMOVNBE, A_FCMOVNE,
  161. A_FCMOVNU, A_FCMOVU, A_FCOM, A_FCOMI, A_FCOMIP, A_FCOMP,
  162. A_FCOMPP, A_FCOS, A_FDECSTP, A_FDISI, A_FDIV, A_FDIVP, A_FDIVR,
  163. A_FDIVRP, A_FEMMS,
  164. A_FENI, A_FFREE, A_FIADD, A_FICOM, A_FICOMP, A_FIDIV,
  165. A_FIDIVR, A_FILD, A_FIMUL, A_FINCSTP, A_FINIT, A_FIST, A_FISTP,
  166. A_FISUB, A_FISUBR, A_FLD, A_FLD1, A_FLDCW, A_FLDENV, A_FLDL2E,
  167. A_FLDL2T, A_FLDLG2, A_FLDLN2, A_FLDPI, A_FLDZ, A_FMUL, A_FMULP,
  168. A_FNCLEX, A_FNDISI, A_FNENI, A_FNINIT, A_FNOP, A_FNSAVE,
  169. A_FNSTCW, A_FNSTENV, A_FNSTSW, A_FPATAN, A_FPREM, A_FPREM1,
  170. A_FPTAN, A_FRNDINT, A_FRSTOR, A_FSAVE, A_FSCALE, A_FSETPM,
  171. A_FSIN, A_FSINCOS, A_FSQRT, A_FST, A_FSTCW, A_FSTENV, A_FSTP,
  172. A_FSTSW, A_FSUB, A_FSUBP, A_FSUBR, A_FSUBRP, A_FTST, A_FUCOM,
  173. A_FUCOMI, A_FUCOMIP, A_FUCOMP, A_FUCOMPP, A_FWAIT,A_FXAM, A_FXCH,
  174. A_FXTRACT, A_FYL2X, A_FYL2XP1, A_HLT, A_IBTS, A_ICEBP, A_IDIV,
  175. A_IMUL, A_IN, A_INC, A_INSB, A_INSD, A_INSW, A_INT,
  176. A_INT01, A_INT1, A_INT3, A_INTO, A_INVD, A_INVLPG, A_IRET,
  177. A_IRETD, A_IRETW, A_JCXZ, A_JECXZ, A_JMP, A_LAHF, A_LAR, A_LDS,
  178. A_LEA, A_LEAVE, A_LES, A_LFS, A_LGDT, A_LGS, A_LIDT, A_LLDT,
  179. A_LMSW, A_LOADALL, A_LOADALL286, A_LODSB, A_LODSD, A_LODSW,
  180. A_LOOP, A_LOOPE, A_LOOPNE, A_LOOPNZ, A_LOOPZ, A_LSL, A_LSS,
  181. A_LTR, A_MOV, A_MOVD, A_MOVQ, A_MOVSB, A_MOVSD, A_MOVSW,
  182. A_MOVSX, A_MOVZX, A_MUL, A_NEG, A_NOP, A_NOT, A_OR, A_OUT,
  183. A_OUTSB, A_OUTSD, A_OUTSW, A_PACKSSDW, A_PACKSSWB, A_PACKUSWB,
  184. A_PADDB, A_PADDD, A_PADDSB, A_PADDSIW, A_PADDSW, A_PADDUSB,
  185. A_PADDUSW, A_PADDW, A_PAND, A_PANDN, A_PAVEB,
  186. A_PAVGUSB, A_PCMPEQB, A_PCMPEQD, A_PCMPEQW, A_PCMPGTB, A_PCMPGTD,
  187. A_PCMPGTW, A_PDISTIB,
  188. A_PF2ID, A_PFACC, A_PFADD, A_PFCMPEQ, A_PFCMPGE, A_PFCMPGT,
  189. A_PFMAX, A_PFMIN, A_PFMUL, A_PFRCP, A_PFRCPIT1, A_PFRCPIT2,
  190. A_PFRSQIT1, A_PFRSQRT, A_PFSUB, A_PFSUBR, A_PI2FD,
  191. A_PMACHRIW, A_PMADDWD, A_PMAGW, A_PMULHRIW, A_PMULHRWA,
  192. A_PMULHRWC, A_PMULHW, A_PMULLW, A_PMVGEZB, A_PMVLZB, A_PMVNZB,
  193. A_PMVZB, A_POP, A_POPA, A_POPAD, A_POPAW, A_POPF, A_POPFD,
  194. A_POPFW, A_POR, A_PREFETCH, A_PREFETCHW,
  195. A_PSLLD, A_PSLLQ, A_PSLLW, A_PSRAD, A_PSRAW,
  196. A_PSRLD, A_PSRLQ, A_PSRLW, A_PSUBB, A_PSUBD, A_PSUBSB,
  197. A_PSUBSIW, A_PSUBSW, A_PSUBUSB, A_PSUBUSW, A_PSUBW, A_PUNPCKHBW,
  198. A_PUNPCKHDQ, A_PUNPCKHWD, A_PUNPCKLBW, A_PUNPCKLDQ, A_PUNPCKLWD,
  199. A_PUSH, A_PUSHA, A_PUSHAD, A_PUSHAW, A_PUSHF, A_PUSHFD,
  200. A_PUSHFW, A_PXOR, A_RCL, A_RCR, A_RDMSR, A_RDPMC, A_RDTSC,
  201. A_RESB, A_RET, A_RETF, A_RETN,
  202. A_ROL, A_ROR, A_RSM, A_SAHF, A_SAL, A_SALC, A_SAR, A_SBB,
  203. A_SCASB, A_SCASD, A_SCASW, A_SGDT, A_SHL, A_SHLD, A_SHR, A_SHRD,
  204. A_SIDT, A_SLDT, A_SMI, A_SMSW, A_STC, A_STD, A_STI, A_STOSB,
  205. A_STOSD, A_STOSW, A_STR, A_SUB, A_TEST, A_UMOV, A_VERR, A_VERW,
  206. A_WAIT, A_WBINVD, A_WRMSR, A_XADD, A_XBTS, A_XCHG, A_XLAT, A_XLATB,
  207. A_XOR, A_CMOVcc, A_Jcc, A_SETcc
  208. );
  209. op2strtable=array[tasmop] of string[10];
  210. const
  211. firstop = low(tasmop);
  212. lastop = high(tasmop);
  213. AsmPrefixes = 6;
  214. AsmPrefix : array[0..AsmPrefixes-1] of TasmOP =(
  215. A_LOCK,A_REP,A_REPE,A_REPNE,A_REPNZ,A_REPZ
  216. );
  217. AsmOverrides = 6;
  218. AsmOverride : array[0..AsmOverrides-1] of TasmOP =(
  219. A_CS,A_ES,A_DS,A_FS,A_GS,A_SS
  220. );
  221. {$ifdef INTELOP}
  222. int_op2str:op2strtable=('<none>',
  223. { prefixes }
  224. 'lock','rep','repe','repne','repnz','repz',
  225. 'segcs','seges','segds','segfs','seggs','segss',
  226. { normal }
  227. 'aaa', 'aad', 'aam', 'aas', 'adc', 'add', 'and', 'arpl',
  228. 'bound', 'bsf', 'bsr', 'bswap', 'bt', 'btc', 'btr', 'bts',
  229. 'call', 'cbw', 'cdq', 'clc', 'cld', 'cli', 'clts', 'cmc', 'cmp',
  230. 'cmpsb', 'cmpsd', 'cmpsw', 'cmpxchg', 'cmpxchg486', 'cmpxchg8b',
  231. 'cpuid', 'cwd', 'cwde', 'daa', 'das', 'dec', 'div', 'emms',
  232. 'enter', 'equ', 'f2xm1', 'fabs',
  233. 'fadd', 'faddp', 'fbld', 'fbstp', 'fchs', 'fclex', 'fcmovb',
  234. 'fcmovbe', 'fcmove', 'fcmovnb', 'fcmovnbe', 'fcmovne',
  235. 'fcmovnu', 'fcmovu', 'fcom', 'fcomi', 'fcomip', 'fcomp',
  236. 'fcompp', 'fcos', 'fdecstp', 'fdisi', 'fdiv', 'fdivp', 'fdivr',
  237. 'fdivrp',
  238. 'femms',
  239. 'feni', 'ffree', 'fiadd', 'ficom', 'ficomp', 'fidiv',
  240. 'fidivr', 'fild', 'fimul', 'fincstp', 'finit', 'fist', 'fistp',
  241. 'fisub', 'fisubr', 'fld', 'fld1', 'fldcw', 'fldenv', 'fldl2e',
  242. 'fldl2t', 'fldlg2', 'fldln2', 'fldpi', 'fldz', 'fmul', 'fmulp',
  243. 'fnclex', 'fndisi', 'fneni', 'fninit', 'fnop', 'fnsave',
  244. 'fnstcw', 'fnstenv', 'fnstsw', 'fpatan', 'fprem', 'fprem1',
  245. 'fptan', 'frndint', 'frstor', 'fsave', 'fscale', 'fsetpm',
  246. 'fsin', 'fsincos', 'fsqrt', 'fst', 'fstcw', 'fstenv', 'fstp',
  247. 'fstsw', 'fsub', 'fsubp', 'fsubr', 'fsubrp', 'ftst', 'fucom',
  248. 'fucomi', 'fucomip', 'fucomp', 'fucompp', 'fwait', 'fxam', 'fxch',
  249. 'fxtract', 'fyl2x', 'fyl2xp1', 'hlt', 'ibts', 'icebp', 'idiv',
  250. 'imul', 'in', 'inc', 'insb', 'insd', 'insw', 'int',
  251. 'int01', 'int1', 'int3', 'into', 'invd', 'invlpg', 'iret',
  252. 'iretd', 'iretw', 'jcxz', 'jecxz', 'jmp', 'lahf', 'lar', 'lds',
  253. 'lea', 'leave', 'les', 'lfs', 'lgdt', 'lgs', 'lidt', 'lldt',
  254. 'lmsw', 'loadall', 'loadall286', 'lodsb', 'lodsd', 'lodsw',
  255. 'loop', 'loope', 'loopne', 'loopnz', 'loopz', 'lsl', 'lss',
  256. 'ltr', 'mov', 'movd', 'movq', 'movsb', 'movsd', 'movsw',
  257. 'movsx', 'movzx', 'mul', 'neg', 'nop', 'not', 'or', 'out',
  258. 'outsb', 'outsd', 'outsw', 'packssdw', 'packsswb', 'packuswb',
  259. 'paddb', 'paddd', 'paddsb', 'paddsiw', 'paddsw', 'paddusb',
  260. 'paddusw', 'paddw', 'pand', 'pandn', 'paveb',
  261. 'pavgusb', 'pcmpeqb',
  262. 'pcmpeqd', 'pcmpeqw', 'pcmpgtb', 'pcmpgtd', 'pcmpgtw',
  263. 'pdistib',
  264. 'pf2id', 'pfacc', 'pfadd', 'pfcmpeq', 'pfcmpge', 'pfcmpgt',
  265. 'pfmax', 'pfmin', 'pfmul', 'pfrcp', 'pfrcpit1', 'pfrcpit2',
  266. 'pfrsqit1', 'pfrsqrt', 'pfsub', 'pfsubr', 'pi2fd',
  267. 'pmachriw', 'pmaddwd', 'pmagw', 'pmulhriw', 'pmulhrwa', 'pmulhrwc',
  268. 'pmulhw', 'pmullw', 'pmvgezb', 'pmvlzb', 'pmvnzb',
  269. 'pmvzb', 'pop', 'popa', 'popad', 'popaw', 'popf', 'popfd',
  270. 'popfw', 'por',
  271. 'prefetch', 'prefetchw', 'pslld', 'psllq', 'psllw', 'psrad', 'psraw',
  272. 'psrld', 'psrlq', 'psrlw', 'psubb', 'psubd', 'psubsb',
  273. 'psubsiw', 'psubsw', 'psubusb', 'psubusw', 'psubw', 'punpckhbw',
  274. 'punpckhdq', 'punpckhwd', 'punpcklbw', 'punpckldq', 'punpcklwd',
  275. 'push', 'pusha', 'pushad', 'pushaw', 'pushf', 'pushfd',
  276. 'pushfw', 'pxor', 'rcl', 'rcr', 'rdmsr', 'rdpmc', 'rdtsc',
  277. 'resb', 'ret', 'retf', 'retn',
  278. 'rol', 'ror', 'rsm', 'sahf', 'sal', 'salc', 'sar', 'sbb',
  279. 'scasb', 'scasd', 'scasw', 'sgdt', 'shl', 'shld', 'shr', 'shrd',
  280. 'sidt', 'sldt', 'smi', 'smsw', 'stc', 'std', 'sti', 'stosb',
  281. 'stosd', 'stosw', 'str', 'sub', 'test', 'umov', 'verr', 'verw',
  282. 'wait', 'wbinvd', 'wrmsr', 'xadd', 'xbts', 'xchg', 'xlat', 'xlatb',
  283. 'xor','cmov','j','set'
  284. );
  285. {$endif INTELOP}
  286. {$ifdef ATTOP}
  287. att_op2str:op2strtable=('<none>',
  288. { prefixes }
  289. 'lock','rep','repe','repne','repnz','repz',
  290. 'cs','es','ds','fs','gs','ss',
  291. { normal }
  292. 'aaa', 'aad', 'aam', 'aas', 'adc', 'add', 'and', 'arpl',
  293. 'bound', 'bsf', 'bsr', 'bswap', 'bt', 'btc', 'btr', 'bts',
  294. 'call', 'cbtw', 'cltd', 'clc', 'cld', 'cli', 'clts', 'cmc', 'cmp',
  295. 'cmpsb', 'cmpsl', 'cmpsw', 'cmpxchg', 'cmpxchg486', 'cmpxchg8b',
  296. 'cpuid', 'cwtd', 'cwtl', 'daa', 'das', 'dec', 'div',
  297. 'emms', 'enter', 'equ', 'f2xm1', 'fabs',
  298. 'fadd', 'faddp', 'fbld', 'fbstp', 'fchs', 'fclex', 'fcmovb',
  299. 'fcmovbe', 'fcmove', 'fcmovnb', 'fcmovnbe', 'fcmovne',
  300. 'fcmovnu', 'fcmovu', 'fcom', 'fcomi', 'fcomip', 'fcomp',
  301. 'fcompp', 'fcos', 'fdecstp', 'fdisi', 'fdiv', 'fdivp', 'fdivr',
  302. 'fdivrp', 'femms',
  303. 'feni', 'ffree', 'fiadd', 'ficom', 'ficomp', 'fidiv',
  304. 'fidivr', 'fild', 'fimul', 'fincstp', 'finit', 'fist', 'fistp',
  305. 'fisub', 'fisubr', 'fld', 'fld1', 'fldcw', 'fldenv', 'fldl2e',
  306. 'fldl2t', 'fldlg2', 'fldln2', 'fldpi', 'fldz', 'fmul', 'fmulp',
  307. 'fnclex', 'fndisi', 'fneni', 'fninit', 'fnop', 'fnsave',
  308. 'fnstcw', 'fnstenv', 'fnstsw', 'fpatan', 'fprem', 'fprem1',
  309. 'fptan', 'frndint', 'frstor', 'fsave', 'fscale', 'fsetpm',
  310. 'fsin', 'fsincos', 'fsqrt', 'fst', 'fstcw', 'fstenv', 'fstp',
  311. 'fstsw', 'fsub', 'fsubp', 'fsubr', 'fsubrp', 'ftst', 'fucom',
  312. 'fucomi', 'fucomip', 'fucomp', 'fucompp', 'fwait', 'fxam', 'fxch',
  313. 'fxtract', 'fyl2x', 'fyl2xp1', 'hlt', 'ibts', 'icebp', 'idiv',
  314. 'imul', 'in', 'inc', 'insb', 'insl', 'insw', 'int',
  315. 'int01', 'int1', 'int3', 'into', 'invd', 'invlpg', 'iret',
  316. 'iretd', 'iretw', 'jcxz', 'jecxz', 'jmp', 'lahf', 'lar', 'lds',
  317. 'lea', 'leave', 'les', 'lfs', 'lgdt', 'lgs', 'lidt', 'lldt',
  318. 'lmsw', 'loadall', 'loadall286', 'lodsb', 'lodsl', 'lodsw',
  319. 'loop', 'loope', 'loopne', 'loopnz', 'loopz', 'lsl', 'lss',
  320. 'ltr', 'mov', 'movd', 'movq', 'movsb', 'movsl', 'movsw',
  321. 'movs', 'movz', 'mul', 'neg', 'nop', 'not', 'or', 'out',
  322. 'outsb', 'outsl', 'outsw', 'packssd', 'packssw', 'packusw',
  323. 'paddb', 'paddd', 'paddsb', 'paddsiw', 'paddsw', 'paddusb',
  324. 'paddusw', 'paddw', 'pand', 'pandn', 'paveb',
  325. 'pavgusb', 'pcmpeqb',
  326. 'pcmpeqd', 'pcmpeqw', 'pcmpgtb', 'pcmpgtd', 'pcmpgtw',
  327. 'pdistib',
  328. 'pf2id', 'pfacc', 'pfadd', 'pfcmpeq', 'pfcmpge', 'pfcmpgt',
  329. 'pfmax', 'pfmin', 'pfmul', 'pfrcp', 'pfrcpit1', 'pfrcpit2',
  330. 'pfrsqit1', 'pfrsqrt', 'pfsub', 'pfsubr', 'pi2fd',
  331. 'pmachriw', 'pmaddwd', 'pmagw', 'pmulhriw', 'pmulhrwa', 'pmulhrwc',
  332. 'pmulhw', 'pmullw', 'pmvgezb', 'pmvlzb', 'pmvnzb',
  333. 'pmvzb', 'pop', 'popa', 'popal', 'popaw', 'popf', 'popfl',
  334. 'popfw', 'por',
  335. 'prefetch', 'prefetchw', 'pslld', 'psllq', 'psllw', 'psrad', 'psraw',
  336. 'psrld', 'psrlq', 'psrlw', 'psubb', 'psubd', 'psubsb',
  337. 'psubsiw', 'psubsw', 'psubusb', 'psubusw', 'psubw', 'punpckhbw',
  338. 'punpckhdq', 'punpckhwd', 'punpcklbw', 'punpckldq', 'punpcklwd',
  339. 'push', 'pusha', 'pushal', 'pushaw', 'pushf', 'pushfl',
  340. 'pushfw', 'pxor', 'rcl', 'rcr', 'rdmsr', 'rdpmc', 'rdtsc',
  341. 'resb', 'ret', 'retf', 'retn',
  342. 'rol', 'ror', 'rsm', 'sahf', 'sal', 'salc', 'sar', 'sbb',
  343. 'scasb', 'scasl', 'scasw', 'sgdt', 'shl', 'shld', 'shr', 'shrd',
  344. 'sidt', 'sldt', 'smi', 'smsw', 'stc', 'std', 'sti', 'stosb',
  345. 'stosl', 'stosw', 'str', 'sub', 'test', 'umov', 'verr', 'verw',
  346. 'wait', 'wbinvd', 'wrmsr', 'xadd', 'xbts', 'xchg', 'xlat', 'xlatb',
  347. 'xor','cmov','j','set'
  348. );
  349. {$endif ATTOP}
  350. {*****************************************************************************
  351. Operand Sizes
  352. *****************************************************************************}
  353. type
  354. topsize = (S_NO,
  355. S_B,S_W,S_L,S_BW,S_BL,S_WL,
  356. S_IS,S_IL,S_IQ,
  357. S_FS,S_FL,S_FX,S_D,S_Q,S_FV
  358. );
  359. const
  360. { Intel style operands ! }
  361. opsize_2_type:array[0..2,topsize] of longint=(
  362. (OT_NONE,
  363. OT_BITS8,OT_BITS16,OT_BITS32,OT_BITS16,OT_BITS32,OT_BITS32,
  364. OT_BITS16,OT_BITS32,OT_BITS64,
  365. OT_BITS32,OT_BITS64,OT_BITS80,OT_BITS64,OT_BITS64,OT_BITS64
  366. ),
  367. (OT_NONE,
  368. OT_BITS8,OT_BITS16,OT_BITS32,OT_BITS8,OT_BITS8,OT_BITS16,
  369. OT_BITS16,OT_BITS32,OT_BITS64,
  370. OT_BITS32,OT_BITS64,OT_BITS80,OT_BITS64,OT_BITS64,OT_BITS64
  371. ),
  372. (OT_NONE,
  373. OT_BITS8,OT_BITS16,OT_BITS32,OT_NONE,OT_NONE,OT_NONE,
  374. OT_BITS16,OT_BITS32,OT_BITS64,
  375. OT_BITS32,OT_BITS64,OT_BITS80,OT_BITS64,OT_BITS64,OT_BITS64
  376. )
  377. );
  378. {$ifdef ATTOP}
  379. att_opsize2str : array[topsize] of string[2] = ('',
  380. 'b','w','l','bw','bl','wl',
  381. 's','l','q',
  382. 's','l','t','d','q','v'
  383. );
  384. {$endif}
  385. {*****************************************************************************
  386. Conditions
  387. *****************************************************************************}
  388. type
  389. TAsmCond=(C_None,
  390. C_A,C_AE,C_B,C_BE,C_C,C_E,C_G,C_GE,C_L,C_LE,C_NA,C_NAE,
  391. C_NB,C_NBE,C_NC,C_NE,C_NG,C_NGE,C_NL,C_NLE,C_NO,C_NP,
  392. C_NS,C_NZ,C_O,C_P,C_PE,C_PO,C_S,C_Z
  393. );
  394. const
  395. cond2str:array[TAsmCond] of string[3]=('',
  396. 'a', 'ae', 'b', 'be', 'c', 'e', 'g', 'ge', 'l', 'le', 'na', 'nae',
  397. 'nb', 'nbe', 'nc', 'ne', 'ng', 'nge', 'nl', 'nle', 'no', 'np',
  398. 'ns', 'nz', 'o', 'p', 'pe', 'po', 's', 'z'
  399. );
  400. inverse_cond:array[TAsmCond] of TAsmCond=(C_None,
  401. C_NA,C_NAE,C_NB,C_NBE,C_NC,C_NE,C_NG,C_NGE,C_NL,C_NLE,C_A,C_AE,
  402. C_B,C_BE,C_C,C_E,C_G,C_GE,C_L,C_LE,C_O,C_P,
  403. C_S,C_Z,C_NO,C_NP,C_NP,C_P,C_NS,C_NZ
  404. );
  405. const
  406. CondAsmOps=3;
  407. CondAsmOp:array[0..CondAsmOps-1] of TasmOp=(
  408. A_CMOVcc, A_Jcc, A_SETcc
  409. );
  410. CondAsmOpStr:array[0..CondAsmOps-1] of string[4]=(
  411. 'CMOV','J','SET'
  412. );
  413. {*****************************************************************************
  414. Registers
  415. *****************************************************************************}
  416. type
  417. { enumeration for registers, don't change the order }
  418. { it's used by the register size conversions }
  419. tregister = (R_NO,
  420. R_EAX,R_ECX,R_EDX,R_EBX,R_ESP,R_EBP,R_ESI,R_EDI,
  421. R_AX,R_CX,R_DX,R_BX,R_SP,R_BP,R_SI,R_DI,
  422. R_AL,R_CL,R_DL,R_BL,R_AH,R_CH,R_BH,R_DH,
  423. { for an easier assembler generation }
  424. R_DEFAULT_SEG,R_CS,R_DS,R_ES,R_SS,R_FS,R_GS,
  425. R_ST,R_ST0,R_ST1,R_ST2,R_ST3,R_ST4,R_ST5,R_ST6,R_ST7,
  426. R_DR0,R_DR1,R_DR2,R_DR3,R_DR6,R_DR7,
  427. R_CR0,R_CR2,R_CR3,R_CR4,
  428. R_TR3,R_TR4,R_TR5,R_TR6,R_TR7,
  429. R_MM0,R_MM1,R_MM2,R_MM3,R_MM4,R_MM5,R_MM6,R_MM7,
  430. R_XMM0,R_XMM1,R_XMM2,R_XMM3,R_XMM4,R_XMM5,R_XMM6,R_XMM7
  431. );
  432. tregisterset = set of tregister;
  433. reg2strtable = array[tregister] of string[6];
  434. const
  435. firstreg = low(tregister);
  436. lastreg = high(tregister);
  437. firstsreg = R_CS;
  438. lastsreg = R_GS;
  439. regset8bit : tregisterset = [R_AL..R_DH];
  440. regset16bit : tregisterset = [R_AX..R_DI,R_CS..R_SS];
  441. regset32bit : tregisterset = [R_EAX..R_EDI];
  442. { Convert reg to opsize }
  443. reg_2_opsize:array[firstreg..lastreg] of topsize = (S_NO,
  444. S_L,S_L,S_L,S_L,S_L,S_L,S_L,S_L,
  445. S_W,S_W,S_W,S_W,S_W,S_W,S_W,S_W,
  446. S_B,S_B,S_B,S_B,S_B,S_B,S_B,S_B,
  447. S_NO,S_W,S_W,S_W,S_W,S_W,S_W,
  448. S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,
  449. S_L,S_L,S_L,S_L,S_L,S_L,
  450. S_L,S_L,S_L,S_L,
  451. S_L,S_L,S_L,S_L,S_L,
  452. S_D,S_D,S_D,S_D,S_D,S_D,S_D,S_D,
  453. S_D,S_D,S_D,S_D,S_D,S_D,S_D,S_D
  454. );
  455. { Convert reg to operand type }
  456. reg_2_type:array[firstreg..lastreg] of longint = (OT_NONE,
  457. OT_REG_EAX,OT_REG_ECX,OT_REG32,OT_REG32,OT_REG32,OT_REG32,OT_REG32,OT_REG32,
  458. OT_REG_AX,OT_REG_CX,OT_REG_DX,OT_REG16,OT_REG16,OT_REG16,OT_REG16,OT_REG16,
  459. OT_REG_AL,OT_REG_CL,OT_REG8,OT_REG8,OT_REG8,OT_REG8,OT_REG8,OT_REG8,
  460. OT_NONE,OT_REG_CS,OT_REG_DESS,OT_REG_DESS,OT_REG_DESS,OT_REG_FSGS,OT_REG_FSGS,
  461. OT_FPU0,OT_FPU0,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,
  462. OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,
  463. OT_REG_CREG,OT_REG_CREG,OT_REG_CREG,OT_REG_CR4,
  464. OT_REG_TREG,OT_REG_TREG,OT_REG_TREG,OT_REG_TREG,OT_REG_TREG,
  465. OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,
  466. OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG
  467. );
  468. {$ifdef INTELOP}
  469. int_reg2str : reg2strtable = ('',
  470. 'eax','ecx','edx','ebx','esp','ebp','esi','edi',
  471. 'ax','cx','dx','bx','sp','bp','si','di',
  472. 'al','cl','dl','bl','ah','ch','bh','dh',
  473. '','cs','ds','es','ss','fs','gs',
  474. 'st','st(0)','st(1)','st(2)','st(3)','st(4)','st(5)','st(6)','st(7)',
  475. 'dr0','dr1','dr2','dr3','dr6','dr7',
  476. 'cr0','cr2','cr3','cr4',
  477. 'tr3','tr4','tr5','tr6','tr7',
  478. 'mm0','mm1','mm2','mm3','mm4','mm5','mm6','mm7',
  479. 'xmm0','xmm1','xmm2','xmm3','xmm4','xmm5','xmm6','xmm7'
  480. );
  481. int_nasmreg2str : reg2strtable = ('',
  482. 'eax','ecx','edx','ebx','esp','ebp','esi','edi',
  483. 'ax','cx','dx','bx','sp','bp','si','di',
  484. 'al','cl','dl','bl','ah','ch','bh','dh',
  485. '','cs','ds','es','ss','fs','gs',
  486. 'st0','st0','st1','st2','st3','st4','st5','st6','st7',
  487. 'dr0','dr1','dr2','dr3','dr6','dr7',
  488. 'cr0','cr2','cr3','cr4',
  489. 'tr3','tr4','tr5','tr6','tr7',
  490. 'mm0','mm1','mm2','mm3','mm4','mm5','mm6','mm7',
  491. 'xmm0','xmm1','xmm2','xmm3','xmm4','xmm5','xmm6','xmm7'
  492. );
  493. {$endif}
  494. {$ifdef ATTREG}
  495. att_reg2str : reg2strtable = ('',
  496. '%eax','%ecx','%edx','%ebx','%esp','%ebp','%esi','%edi',
  497. '%ax','%cx','%dx','%bx','%sp','%bp','%si','%di',
  498. '%al','%cl','%dl','%bl','%ah','%ch','%bh','%dh',
  499. '','%cs','%ds','%es','%ss','%fs','%gs',
  500. '%st','%st(0)','%st(1)','%st(2)','%st(3)','%st(4)','%st(5)','%st(6)','%st(7)',
  501. '%dr0','%dr1','%dr2','%dr3','%dr6','%dr7',
  502. '%cr0','%cr2','%cr3','%cr4',
  503. '%tr3','%tr4','%tr5','%tr6','%tr7',
  504. '%mm0','%mm1','%mm2','%mm3','%mm4','%mm5','%mm6','%mm7',
  505. '%xmm0','%xmm1','%xmm2','%xmm3','%xmm4','%xmm5','%xmm6','%xmm7'
  506. );
  507. {$endif ATTREG}
  508. {*****************************************************************************
  509. Flags
  510. *****************************************************************************}
  511. type
  512. TResFlags = (F_E,F_NE,F_G,F_L,F_GE,F_LE,F_C,F_NC,F_A,F_AE,F_B,F_BE);
  513. const
  514. { arrays for boolean location conversions }
  515. flag_2_cond : array[TResFlags] of TAsmCond =
  516. (C_E,C_NE,C_G,C_L,C_GE,C_LE,C_C,C_NC,C_A,C_AE,C_B,C_BE);
  517. {*****************************************************************************
  518. Reference
  519. *****************************************************************************}
  520. type
  521. trefoptions=(ref_none,ref_parafixup,ref_localfixup);
  522. { immediate/reference record }
  523. preference = ^treference;
  524. treference = record
  525. is_immediate : boolean; { is this used as reference or immediate }
  526. segment,
  527. base,
  528. index : tregister;
  529. scalefactor : byte;
  530. offset : longint;
  531. symbol : pasmsymbol;
  532. offsetfixup : longint;
  533. options : trefoptions;
  534. end;
  535. {*****************************************************************************
  536. Generic Location
  537. *****************************************************************************}
  538. type
  539. TLoc=(
  540. LOC_INVALID, { added for tracking problems}
  541. LOC_FPU, { FPU stack }
  542. LOC_REGISTER, { in a processor register }
  543. LOC_MEM, { in memory }
  544. LOC_REFERENCE, { like LOC_MEM, but lvalue }
  545. LOC_JUMP, { boolean results only, jump to false or true label }
  546. LOC_FLAGS, { boolean results only, flags are set }
  547. LOC_CREGISTER, { Constant register which shouldn't be modified }
  548. LOC_MMXREGISTER, { MMX register }
  549. LOC_CMMXREGISTER { Constant MMX register }
  550. );
  551. plocation = ^tlocation;
  552. tlocation = packed record
  553. case loc : tloc of
  554. LOC_MEM,LOC_REFERENCE : (reference : treference);
  555. LOC_FPU : ();
  556. LOC_JUMP : ();
  557. LOC_FLAGS : (resflags : tresflags);
  558. LOC_INVALID : ();
  559. { it's only for better handling }
  560. LOC_MMXREGISTER : (mmxreg : tregister);
  561. { segment in reference at the same place as in loc_register }
  562. LOC_REGISTER,LOC_CREGISTER : (
  563. case longint of
  564. 1 : (register,segment,registerhigh : tregister);
  565. { overlay a registerlow }
  566. 2 : (registerlow : tregister);
  567. );
  568. end;
  569. {*****************************************************************************
  570. Constants
  571. *****************************************************************************}
  572. type
  573. tcpuflags = (cf_registers64);
  574. const
  575. general_registers = [R_EAX,R_EBX,R_ECX,R_EDX];
  576. registers_saved_on_cdecl = [R_ESI,R_EDI,R_EBX];
  577. { generic register names }
  578. stack_pointer = R_ESP;
  579. frame_pointer = R_EBP;
  580. self_pointer = R_ESI;
  581. accumulator = R_EAX;
  582. cpuflags : set of tcpuflags = [];
  583. { sizes }
  584. pointersize = 4;
  585. extended_size = 10;
  586. sizepostfix_pointer = S_L;
  587. {*****************************************************************************
  588. Instruction table
  589. *****************************************************************************}
  590. type
  591. tinsentry=packed record
  592. opcode : tasmop;
  593. ops : byte;
  594. optypes : array[0..2] of longint;
  595. code : array[0..maxinfolen] of char;
  596. flags : longint;
  597. end;
  598. pinsentry=^tinsentry;
  599. TInsTabCache=array[TasmOp] of longint;
  600. PInsTabCache=^TInsTabCache;
  601. const
  602. InsTab:array[0..instabentries-1] of TInsEntry=
  603. {$i i386tab.inc}
  604. var
  605. InsTabCache : PInsTabCache;
  606. {*****************************************************************************
  607. Helpers
  608. *****************************************************************************}
  609. const
  610. maxvarregs = 4;
  611. varregs : array[1..maxvarregs] of tregister =
  612. (R_EBX,R_EDX,R_ECX,R_EAX);
  613. function imm_2_type(l:longint):longint;
  614. { the following functions allow to convert registers }
  615. { for example reg8toreg32(R_AL) returns R_EAX }
  616. { for example reg16toreg32(R_AL) gives an undefined }
  617. { result }
  618. { these functions expects that the turn of }
  619. { tregister isn't changed }
  620. function reg8toreg16(reg : tregister) : tregister;
  621. function reg8toreg32(reg : tregister) : tregister;
  622. function reg16toreg8(reg : tregister) : tregister;
  623. function reg32toreg8(reg : tregister) : tregister;
  624. function reg32toreg16(reg : tregister) : tregister;
  625. function reg16toreg32(reg : tregister) : tregister;
  626. { these procedures must be defined by all target cpus }
  627. function regtoreg8(reg : tregister) : tregister;
  628. function regtoreg16(reg : tregister) : tregister;
  629. function regtoreg32(reg : tregister) : tregister;
  630. { can be ignored on 32 bit systems }
  631. function regtoreg64(reg : tregister) : tregister;
  632. { returns the operand prefix for a given register }
  633. function regsize(reg : tregister) : topsize;
  634. { resets all values of ref to defaults }
  635. procedure reset_reference(var ref : treference);
  636. { set mostly used values of a new reference }
  637. function new_reference(base : tregister;offset : longint) : preference;
  638. { same as reset_reference, but symbol is disposed }
  639. { use this only for already used references }
  640. procedure clear_reference(var ref : treference);
  641. function newreference(const r : treference) : preference;
  642. procedure disposereference(var r : preference);
  643. function reg2str(r : tregister) : string;
  644. implementation
  645. {*****************************************************************************
  646. Helpers
  647. *****************************************************************************}
  648. function imm_2_type(l:longint):longint;
  649. begin
  650. if (l>=-128) and (l<=127) then
  651. imm_2_type:=OT_IMM8 or OT_SIGNED
  652. else
  653. if (l>=-255) and (l<=255) then
  654. imm_2_type:=OT_IMM8
  655. else
  656. if (l>=-32768) and (l<=32767) then
  657. imm_2_type:=OT_IMM16 or OT_SIGNED
  658. else
  659. if (l>=-65536) and (l<=65535) then
  660. imm_2_type:=OT_IMM16 or OT_SIGNED
  661. else
  662. imm_2_type:=OT_IMM32;
  663. end;
  664. function reg2str(r : tregister) : string;
  665. const
  666. a : array[R_NO..R_BL] of string[3] =
  667. ('','EAX','ECX','EDX','EBX','ESP','EBP','ESI','EDI',
  668. 'AX','CX','DX','BX','SP','BP','SI','DI',
  669. 'AL','CL','DL','BL');
  670. begin
  671. reg2str:=a[r];
  672. end;
  673. procedure disposereference(var r : preference);
  674. begin
  675. dispose(r);
  676. r:=nil;
  677. end;
  678. function newreference(const r : treference) : preference;
  679. var
  680. p : preference;
  681. begin
  682. new(p);
  683. p^:=r;
  684. newreference:=p;
  685. end;
  686. function reg8toreg16(reg : tregister) : tregister;
  687. begin
  688. reg8toreg16:=reg32toreg16(reg8toreg32(reg));
  689. end;
  690. function reg16toreg8(reg : tregister) : tregister;
  691. begin
  692. reg16toreg8:=reg32toreg8(reg16toreg32(reg));
  693. end;
  694. function reg16toreg32(reg : tregister) : tregister;
  695. begin
  696. reg16toreg32:=tregister(byte(reg)-byte(R_EDI));
  697. end;
  698. function reg32toreg16(reg : tregister) : tregister;
  699. begin
  700. reg32toreg16:=tregister(byte(reg)+byte(R_EDI));
  701. end;
  702. function reg32toreg8(reg : tregister) : tregister;
  703. begin
  704. reg32toreg8:=tregister(byte(reg)+byte(R_DI));
  705. end;
  706. function reg8toreg32(reg : tregister) : tregister;
  707. begin
  708. reg8toreg32:=tregister(byte(reg)-byte(R_DI));
  709. end;
  710. function regtoreg8(reg : tregister) : tregister;
  711. begin
  712. regtoreg8:=reg32toreg8(reg);
  713. end;
  714. function regtoreg16(reg : tregister) : tregister;
  715. begin
  716. regtoreg16:=reg32toreg16(reg);
  717. end;
  718. function regtoreg32(reg : tregister) : tregister;
  719. begin
  720. regtoreg32:=reg;
  721. end;
  722. function regtoreg64(reg : tregister) : tregister;
  723. begin
  724. { to avoid warning }
  725. regtoreg64:=R_NO;
  726. end;
  727. function regsize(reg : tregister) : topsize;
  728. begin
  729. if reg in regset8bit then
  730. regsize:=S_B
  731. else if reg in regset16bit then
  732. regsize:=S_W
  733. else if reg in regset32bit then
  734. regsize:=S_L;
  735. end;
  736. procedure reset_reference(var ref : treference);
  737. begin
  738. with ref do
  739. begin
  740. is_immediate:=false;
  741. segment:=R_DEFAULT_SEG;
  742. base:=R_NO;
  743. index:=R_NO;
  744. scalefactor:=0;
  745. offset:=0;
  746. symbol:=nil;
  747. offsetfixup:=0;
  748. options:=ref_none;
  749. end;
  750. end;
  751. function new_reference(base : tregister;offset : longint) : preference;
  752. var
  753. r : preference;
  754. begin
  755. new(r);
  756. reset_reference(r^);
  757. r^.base:=base;
  758. r^.offset:=offset;
  759. new_reference:=r;
  760. end;
  761. procedure clear_reference(var ref : treference);
  762. begin
  763. reset_reference(ref);
  764. end;
  765. {*****************************************************************************
  766. Instruction table
  767. *****************************************************************************}
  768. var
  769. saveexit : pointer;
  770. procedure FreeInsTabCache;{$ifndef FPC}far;{$endif}
  771. begin
  772. exitproc:=saveexit;
  773. dispose(instabcache);
  774. end;
  775. procedure BuildInsTabCache;
  776. var
  777. i : longint;
  778. begin
  779. new(instabcache);
  780. FillChar(instabcache^,sizeof(tinstabcache),$ff);
  781. i:=0;
  782. while (i<InsTabEntries) do
  783. begin
  784. if InsTabCache^[InsTab[i].OPcode]=-1 then
  785. InsTabCache^[InsTab[i].OPcode]:=i;
  786. inc(i);
  787. end;
  788. saveexit:=exitproc;
  789. exitproc:=@FreeInsTabCache;
  790. end;
  791. begin
  792. BuildInsTabCache;
  793. end.
  794. {
  795. $Log$
  796. Revision 1.1 1999-05-01 13:24:23 peter
  797. * merged nasm compiler
  798. * old asm moved to oldasm/
  799. Revision 1.13 1999/04/14 09:07:43 peter
  800. * asm reader improvements
  801. Revision 1.12 1999/04/10 16:14:09 peter
  802. * fixed optimizer
  803. Revision 1.11 1999/03/31 13:55:33 peter
  804. * assembler inlining working for ag386bin
  805. Revision 1.10 1999/03/29 16:05:50 peter
  806. * optimizer working for ag386bin
  807. Revision 1.9 1999/03/26 00:01:14 peter
  808. * first things for optimizer (compiles but cycle crashes)
  809. Revision 1.8 1999/03/06 17:24:21 peter
  810. * rewritten intel parser a lot, especially reference reading
  811. * size checking added for asm parsers
  812. Revision 1.7 1999/03/02 02:56:20 peter
  813. + stabs support for binary writers
  814. * more fixes and missing updates from the previous commit :(
  815. Revision 1.6 1999/03/01 15:46:22 peter
  816. * ag386bin finally make cycles correct
  817. * prefixes are now also normal opcodes
  818. Revision 1.5 1999/02/26 00:48:29 peter
  819. * assembler writers fixed for ag386bin
  820. Revision 1.4 1999/02/25 21:03:04 peter
  821. * ag386bin updates
  822. + coff writer
  823. Revision 1.3 1999/02/22 02:44:18 peter
  824. * ag386bin doesn't use i386.pas anymore
  825. Revision 1.2 1999/02/22 02:16:03 peter
  826. * updates for ag386bin
  827. Revision 1.1 1999/02/16 17:59:38 peter
  828. + initial files
  829. }