cpubase.pas 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101
  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 cpubase;
  22. interface
  23. {$ifdef TP}
  24. {$L-,Y-}
  25. {$endif}
  26. uses
  27. globals,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. att_nosuffix:array[tasmop] of boolean=(
  350. { 0 }
  351. false,false,false,false,false,false,false,false,false,false,
  352. false,false,false,false,false,false,false,false,false,false,
  353. false,false,false,false,false,false,false,false,false,false,
  354. false,false,false,false,false,false,false,false,false,false,
  355. false,false,false,false,false,false,false,false,false,false,
  356. false,false,false,false,false,false,false,false,false,false,
  357. false,false,false,false,false,false,false,false,false,false,
  358. false,false,false,false,false,false,false,false,false,false,
  359. false,false,false,false,false,false,false,false,false,false,
  360. false,false,false,false,false,false,false,false,false,false,
  361. { 100 }
  362. false,false,false,false,false,false,false,false,false,false,
  363. false,false,false,false,false,false,false,false,false,false,
  364. false,false,false,false,false,false,false,false,false,false,
  365. false,false,false,false,false,false,false,false,false,false,
  366. false,false,false,false,false,false,false,false,false,false,
  367. false,false,false,false,false,false,false,false,false,false,
  368. false,false,false,false,false,false,false,false,false,false,
  369. false,false,false,false,false,false,false,false,false,false,
  370. false,false,false,false,false,false,false,false,false,false,
  371. false,false,false,false,false,false,false,false,false,false,
  372. { 200 }
  373. false,true,true,true,true,true,false,false,false,false,
  374. false,false,false,false,false,false,false,false,false,false,
  375. true,true,true,true,true,true,true,true,true,true,
  376. true,true,true,true,true,true,true,true,true,true,
  377. true,true,true,true,true,true,true,true,true,true,
  378. true,true,true,true,true,true,true,true,true,true,
  379. true,true,true,true,true,true,true,true,false,false,
  380. false,false,false,false,false,false,false,false,true,true,
  381. true,true,true,true,true,true,true,true,true,true,
  382. true,true,true,true,true,true,true,true,true,true,
  383. { 300 }
  384. false,false,true,true,false,true,true,true,false,false,
  385. false,false,false,false,false,false,false,false,false,false,
  386. false,false,false,false,false,false,false,false,false,false,
  387. false,false,false,false,false,false,false,false,false,false,
  388. false,false,false,false,false,false,false,false,false,false,
  389. false,false,false,false,false,false,false,false,false,false,
  390. false
  391. );
  392. {$endif ATTOP}
  393. {*****************************************************************************
  394. Operand Sizes
  395. *****************************************************************************}
  396. type
  397. topsize = (S_NO,
  398. S_B,S_W,S_L,S_BW,S_BL,S_WL,
  399. S_IS,S_IL,S_IQ,
  400. S_FS,S_FL,S_FX,S_D,S_Q,S_FV
  401. );
  402. const
  403. { Intel style operands ! }
  404. opsize_2_type:array[0..2,topsize] of longint=(
  405. (OT_NONE,
  406. OT_BITS8,OT_BITS16,OT_BITS32,OT_BITS16,OT_BITS32,OT_BITS32,
  407. OT_BITS16,OT_BITS32,OT_BITS64,
  408. OT_BITS32,OT_BITS64,OT_BITS80,OT_BITS64,OT_BITS64,OT_BITS64
  409. ),
  410. (OT_NONE,
  411. OT_BITS8,OT_BITS16,OT_BITS32,OT_BITS8,OT_BITS8,OT_BITS16,
  412. OT_BITS16,OT_BITS32,OT_BITS64,
  413. OT_BITS32,OT_BITS64,OT_BITS80,OT_BITS64,OT_BITS64,OT_BITS64
  414. ),
  415. (OT_NONE,
  416. OT_BITS8,OT_BITS16,OT_BITS32,OT_NONE,OT_NONE,OT_NONE,
  417. OT_BITS16,OT_BITS32,OT_BITS64,
  418. OT_BITS32,OT_BITS64,OT_BITS80,OT_BITS64,OT_BITS64,OT_BITS64
  419. )
  420. );
  421. {$ifdef ATTOP}
  422. att_opsize2str : array[topsize] of string[2] = ('',
  423. 'b','w','l','bw','bl','wl',
  424. 's','l','q',
  425. 's','l','t','d','q','v'
  426. );
  427. {$endif}
  428. {*****************************************************************************
  429. Conditions
  430. *****************************************************************************}
  431. type
  432. TAsmCond=(C_None,
  433. C_A,C_AE,C_B,C_BE,C_C,C_E,C_G,C_GE,C_L,C_LE,C_NA,C_NAE,
  434. C_NB,C_NBE,C_NC,C_NE,C_NG,C_NGE,C_NL,C_NLE,C_NO,C_NP,
  435. C_NS,C_NZ,C_O,C_P,C_PE,C_PO,C_S,C_Z
  436. );
  437. const
  438. cond2str:array[TAsmCond] of string[3]=('',
  439. 'a', 'ae', 'b', 'be', 'c', 'e', 'g', 'ge', 'l', 'le', 'na', 'nae',
  440. 'nb', 'nbe', 'nc', 'ne', 'ng', 'nge', 'nl', 'nle', 'no', 'np',
  441. 'ns', 'nz', 'o', 'p', 'pe', 'po', 's', 'z'
  442. );
  443. inverse_cond:array[TAsmCond] of TAsmCond=(C_None,
  444. C_NA,C_NAE,C_NB,C_NBE,C_NC,C_NE,C_NG,C_NGE,C_NL,C_NLE,C_A,C_AE,
  445. C_B,C_BE,C_C,C_E,C_G,C_GE,C_L,C_LE,C_O,C_P,
  446. C_S,C_Z,C_NO,C_NP,C_NP,C_P,C_NS,C_NZ
  447. );
  448. const
  449. CondAsmOps=3;
  450. CondAsmOp:array[0..CondAsmOps-1] of TasmOp=(
  451. A_CMOVcc, A_Jcc, A_SETcc
  452. );
  453. CondAsmOpStr:array[0..CondAsmOps-1] of string[4]=(
  454. 'CMOV','J','SET'
  455. );
  456. {*****************************************************************************
  457. Registers
  458. *****************************************************************************}
  459. type
  460. { enumeration for registers, don't change the order }
  461. { it's used by the register size conversions }
  462. tregister = (R_NO,
  463. R_EAX,R_ECX,R_EDX,R_EBX,R_ESP,R_EBP,R_ESI,R_EDI,
  464. R_AX,R_CX,R_DX,R_BX,R_SP,R_BP,R_SI,R_DI,
  465. R_AL,R_CL,R_DL,R_BL,R_AH,R_CH,R_BH,R_DH,
  466. R_CS,R_DS,R_ES,R_SS,R_FS,R_GS,
  467. R_ST,R_ST0,R_ST1,R_ST2,R_ST3,R_ST4,R_ST5,R_ST6,R_ST7,
  468. R_DR0,R_DR1,R_DR2,R_DR3,R_DR6,R_DR7,
  469. R_CR0,R_CR2,R_CR3,R_CR4,
  470. R_TR3,R_TR4,R_TR5,R_TR6,R_TR7,
  471. R_MM0,R_MM1,R_MM2,R_MM3,R_MM4,R_MM5,R_MM6,R_MM7,
  472. R_XMM0,R_XMM1,R_XMM2,R_XMM3,R_XMM4,R_XMM5,R_XMM6,R_XMM7
  473. );
  474. tregisterset = set of tregister;
  475. reg2strtable = array[tregister] of string[6];
  476. const
  477. firstreg = low(tregister);
  478. lastreg = high(tregister);
  479. firstsreg = R_CS;
  480. lastsreg = R_GS;
  481. regset8bit : tregisterset = [R_AL..R_DH];
  482. regset16bit : tregisterset = [R_AX..R_DI,R_CS..R_SS];
  483. regset32bit : tregisterset = [R_EAX..R_EDI];
  484. { Convert reg to opsize }
  485. reg_2_opsize:array[firstreg..lastreg] of topsize = (S_NO,
  486. S_L,S_L,S_L,S_L,S_L,S_L,S_L,S_L,
  487. S_W,S_W,S_W,S_W,S_W,S_W,S_W,S_W,
  488. S_B,S_B,S_B,S_B,S_B,S_B,S_B,S_B,
  489. S_W,S_W,S_W,S_W,S_W,S_W,
  490. S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,
  491. S_L,S_L,S_L,S_L,S_L,S_L,
  492. S_L,S_L,S_L,S_L,
  493. S_L,S_L,S_L,S_L,S_L,
  494. S_D,S_D,S_D,S_D,S_D,S_D,S_D,S_D,
  495. S_D,S_D,S_D,S_D,S_D,S_D,S_D,S_D
  496. );
  497. { Convert reg to operand type }
  498. reg_2_type:array[firstreg..lastreg] of longint = (OT_NONE,
  499. OT_REG_EAX,OT_REG_ECX,OT_REG32,OT_REG32,OT_REG32,OT_REG32,OT_REG32,OT_REG32,
  500. OT_REG_AX,OT_REG_CX,OT_REG_DX,OT_REG16,OT_REG16,OT_REG16,OT_REG16,OT_REG16,
  501. OT_REG_AL,OT_REG_CL,OT_REG8,OT_REG8,OT_REG8,OT_REG8,OT_REG8,OT_REG8,
  502. OT_REG_CS,OT_REG_DESS,OT_REG_DESS,OT_REG_DESS,OT_REG_FSGS,OT_REG_FSGS,
  503. OT_FPU0,OT_FPU0,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,
  504. OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,
  505. OT_REG_CREG,OT_REG_CREG,OT_REG_CREG,OT_REG_CR4,
  506. OT_REG_TREG,OT_REG_TREG,OT_REG_TREG,OT_REG_TREG,OT_REG_TREG,
  507. OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,
  508. OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG
  509. );
  510. {$ifdef INTELOP}
  511. int_reg2str : reg2strtable = ('',
  512. 'eax','ecx','edx','ebx','esp','ebp','esi','edi',
  513. 'ax','cx','dx','bx','sp','bp','si','di',
  514. 'al','cl','dl','bl','ah','ch','bh','dh',
  515. 'cs','ds','es','ss','fs','gs',
  516. 'st','st(0)','st(1)','st(2)','st(3)','st(4)','st(5)','st(6)','st(7)',
  517. 'dr0','dr1','dr2','dr3','dr6','dr7',
  518. 'cr0','cr2','cr3','cr4',
  519. 'tr3','tr4','tr5','tr6','tr7',
  520. 'mm0','mm1','mm2','mm3','mm4','mm5','mm6','mm7',
  521. 'xmm0','xmm1','xmm2','xmm3','xmm4','xmm5','xmm6','xmm7'
  522. );
  523. int_nasmreg2str : reg2strtable = ('',
  524. 'eax','ecx','edx','ebx','esp','ebp','esi','edi',
  525. 'ax','cx','dx','bx','sp','bp','si','di',
  526. 'al','cl','dl','bl','ah','ch','bh','dh',
  527. 'cs','ds','es','ss','fs','gs',
  528. 'st0','st0','st1','st2','st3','st4','st5','st6','st7',
  529. 'dr0','dr1','dr2','dr3','dr6','dr7',
  530. 'cr0','cr2','cr3','cr4',
  531. 'tr3','tr4','tr5','tr6','tr7',
  532. 'mm0','mm1','mm2','mm3','mm4','mm5','mm6','mm7',
  533. 'xmm0','xmm1','xmm2','xmm3','xmm4','xmm5','xmm6','xmm7'
  534. );
  535. {$endif}
  536. {$ifdef ATTREG}
  537. att_reg2str : reg2strtable = ('',
  538. '%eax','%ecx','%edx','%ebx','%esp','%ebp','%esi','%edi',
  539. '%ax','%cx','%dx','%bx','%sp','%bp','%si','%di',
  540. '%al','%cl','%dl','%bl','%ah','%ch','%bh','%dh',
  541. '%cs','%ds','%es','%ss','%fs','%gs',
  542. '%st','%st(0)','%st(1)','%st(2)','%st(3)','%st(4)','%st(5)','%st(6)','%st(7)',
  543. '%dr0','%dr1','%dr2','%dr3','%dr6','%dr7',
  544. '%cr0','%cr2','%cr3','%cr4',
  545. '%tr3','%tr4','%tr5','%tr6','%tr7',
  546. '%mm0','%mm1','%mm2','%mm3','%mm4','%mm5','%mm6','%mm7',
  547. '%xmm0','%xmm1','%xmm2','%xmm3','%xmm4','%xmm5','%xmm6','%xmm7'
  548. );
  549. {$endif ATTREG}
  550. {*****************************************************************************
  551. Flags
  552. *****************************************************************************}
  553. type
  554. 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);
  555. const
  556. { arrays for boolean location conversions }
  557. flag_2_cond : array[TResFlags] of TAsmCond =
  558. (C_E,C_NE,C_G,C_L,C_GE,C_LE,C_C,C_NC,C_A,C_AE,C_B,C_BE);
  559. {*****************************************************************************
  560. Reference
  561. *****************************************************************************}
  562. type
  563. trefoptions=(ref_none,ref_parafixup,ref_localfixup);
  564. { immediate/reference record }
  565. preference = ^treference;
  566. treference = packed record
  567. is_immediate : boolean; { is this used as reference or immediate }
  568. segment,
  569. base,
  570. index : tregister;
  571. scalefactor : byte;
  572. offset : longint;
  573. symbol : pasmsymbol;
  574. offsetfixup : longint;
  575. options : trefoptions;
  576. end;
  577. {*****************************************************************************
  578. Operands
  579. *****************************************************************************}
  580. { Types of operand }
  581. toptype=(top_none,top_reg,top_ref,top_const,top_symbol);
  582. toper=record
  583. ot : longint;
  584. case typ : toptype of
  585. top_none : ();
  586. top_reg : (reg:tregister);
  587. top_ref : (ref:preference);
  588. top_const : (val:longint);
  589. top_symbol : (sym:pasmsymbol;symofs:longint);
  590. end;
  591. {*****************************************************************************
  592. Generic Location
  593. *****************************************************************************}
  594. type
  595. TLoc=(
  596. LOC_INVALID, { added for tracking problems}
  597. LOC_FPU, { FPU stack }
  598. LOC_REGISTER, { in a processor register }
  599. LOC_MEM, { in memory }
  600. LOC_REFERENCE, { like LOC_MEM, but lvalue }
  601. LOC_JUMP, { boolean results only, jump to false or true label }
  602. LOC_FLAGS, { boolean results only, flags are set }
  603. LOC_CREGISTER, { Constant register which shouldn't be modified }
  604. LOC_MMXREGISTER, { MMX register }
  605. LOC_CMMXREGISTER,{ Constant MMX register }
  606. LOC_CFPUREGISTER { if it is a FPU register variable on the fpu stack }
  607. );
  608. plocation = ^tlocation;
  609. tlocation = packed record
  610. case loc : tloc of
  611. LOC_MEM,LOC_REFERENCE : (reference : treference);
  612. LOC_FPU : ();
  613. LOC_JUMP : ();
  614. LOC_FLAGS : (resflags : tresflags);
  615. LOC_INVALID : ();
  616. { it's only for better handling }
  617. LOC_MMXREGISTER : (mmxreg : tregister);
  618. { segment in reference at the same place as in loc_register }
  619. LOC_REGISTER,LOC_CREGISTER : (
  620. case longint of
  621. 1 : (register,segment,registerhigh : tregister);
  622. { overlay a registerlow }
  623. 2 : (registerlow : tregister);
  624. );
  625. end;
  626. {*****************************************************************************
  627. Constants
  628. *****************************************************************************}
  629. type
  630. tcpuflags = (cf_registers64);
  631. const
  632. general_registers = [R_EAX,R_EBX,R_ECX,R_EDX];
  633. intregs = general_registers;
  634. fpuregs = [];
  635. mmregs = [R_MM0..R_MM7];
  636. registers_saved_on_cdecl = [R_ESI,R_EDI,R_EBX];
  637. { generic register names }
  638. stack_pointer = R_ESP;
  639. frame_pointer = R_EBP;
  640. self_pointer = R_ESI;
  641. accumulator = R_EAX;
  642. cpuflags : set of tcpuflags = [];
  643. { sizes }
  644. pointersize = 4;
  645. extended_size = 10;
  646. sizepostfix_pointer = S_L;
  647. {*****************************************************************************
  648. Instruction table
  649. *****************************************************************************}
  650. {$ifndef NOAG386BIN}
  651. type
  652. tinsentry=packed record
  653. opcode : tasmop;
  654. ops : byte;
  655. optypes : array[0..2] of longint;
  656. code : array[0..maxinfolen] of char;
  657. flags : longint;
  658. end;
  659. pinsentry=^tinsentry;
  660. TInsTabCache=array[TasmOp] of longint;
  661. PInsTabCache=^TInsTabCache;
  662. const
  663. InsTab:array[0..instabentries-1] of TInsEntry=
  664. {$i i386tab.inc}
  665. var
  666. InsTabCache : PInsTabCache;
  667. {$endif NOAG386BIN}
  668. {*****************************************************************************
  669. Helpers
  670. *****************************************************************************}
  671. const
  672. maxvarregs = 4;
  673. varregs : array[1..maxvarregs] of tregister =
  674. (R_EBX,R_EDX,R_ECX,R_EAX);
  675. maxfpuvarregs = 8;
  676. function imm_2_type(l:longint):longint;
  677. { the following functions allow to convert registers }
  678. { for example reg8toreg32(R_AL) returns R_EAX }
  679. { for example reg16toreg32(R_AL) gives an undefined }
  680. { result }
  681. { these functions expects that the turn of }
  682. { tregister isn't changed }
  683. function reg8toreg16(reg : tregister) : tregister;
  684. function reg8toreg32(reg : tregister) : tregister;
  685. function reg16toreg8(reg : tregister) : tregister;
  686. function reg32toreg8(reg : tregister) : tregister;
  687. function reg32toreg16(reg : tregister) : tregister;
  688. function reg16toreg32(reg : tregister) : tregister;
  689. { these procedures must be defined by all target cpus }
  690. function regtoreg8(reg : tregister) : tregister;
  691. function regtoreg16(reg : tregister) : tregister;
  692. function regtoreg32(reg : tregister) : tregister;
  693. { can be ignored on 32 bit systems }
  694. function regtoreg64(reg : tregister) : tregister;
  695. { returns the operand prefix for a given register }
  696. function regsize(reg : tregister) : topsize;
  697. { resets all values of ref to defaults }
  698. procedure reset_reference(var ref : treference);
  699. { set mostly used values of a new reference }
  700. function new_reference(base : tregister;offset : longint) : preference;
  701. function newreference(const r : treference) : preference;
  702. procedure disposereference(var r : preference);
  703. function reg2str(r : tregister) : string;
  704. function is_calljmp(o:tasmop):boolean;
  705. implementation
  706. {$ifdef heaptrc}
  707. uses
  708. ppheap;
  709. {$endif heaptrc}
  710. {*****************************************************************************
  711. Helpers
  712. *****************************************************************************}
  713. function imm_2_type(l:longint):longint;
  714. begin
  715. if (l>=-128) and (l<=127) then
  716. imm_2_type:=OT_IMM8 or OT_SIGNED
  717. else
  718. if (l>=-255) and (l<=255) then
  719. imm_2_type:=OT_IMM8
  720. else
  721. if (l>=-32768) and (l<=32767) then
  722. imm_2_type:=OT_IMM16 or OT_SIGNED
  723. else
  724. if (l>=-65536) and (l<=65535) then
  725. imm_2_type:=OT_IMM16 or OT_SIGNED
  726. else
  727. imm_2_type:=OT_IMM32;
  728. end;
  729. function reg2str(r : tregister) : string;
  730. const
  731. a : array[R_NO..R_BL] of string[3] =
  732. ('','EAX','ECX','EDX','EBX','ESP','EBP','ESI','EDI',
  733. 'AX','CX','DX','BX','SP','BP','SI','DI',
  734. 'AL','CL','DL','BL');
  735. begin
  736. if r in [R_ST0..R_ST7] then
  737. reg2str:='ST('+tostr(longint(r)-longint(R_ST0))+')'
  738. else
  739. reg2str:=a[r];
  740. end;
  741. function is_calljmp(o:tasmop):boolean;
  742. begin
  743. case o of
  744. A_CALL,
  745. A_JCXZ,
  746. A_JECXZ,
  747. A_JMP,
  748. A_LOOP,
  749. A_Jcc :
  750. is_calljmp:=true;
  751. else
  752. is_calljmp:=false;
  753. end;
  754. end;
  755. procedure disposereference(var r : preference);
  756. begin
  757. dispose(r);
  758. r:=nil;
  759. end;
  760. function newreference(const r : treference) : preference;
  761. var
  762. p : preference;
  763. begin
  764. new(p);
  765. p^:=r;
  766. newreference:=p;
  767. end;
  768. function reg8toreg16(reg : tregister) : tregister;
  769. begin
  770. reg8toreg16:=reg32toreg16(reg8toreg32(reg));
  771. end;
  772. function reg16toreg8(reg : tregister) : tregister;
  773. begin
  774. reg16toreg8:=reg32toreg8(reg16toreg32(reg));
  775. end;
  776. function reg16toreg32(reg : tregister) : tregister;
  777. begin
  778. reg16toreg32:=tregister(byte(reg)-byte(R_EDI));
  779. end;
  780. function reg32toreg16(reg : tregister) : tregister;
  781. begin
  782. reg32toreg16:=tregister(byte(reg)+byte(R_EDI));
  783. end;
  784. function reg32toreg8(reg : tregister) : tregister;
  785. begin
  786. reg32toreg8:=tregister(byte(reg)+byte(R_DI));
  787. end;
  788. function reg8toreg32(reg : tregister) : tregister;
  789. begin
  790. reg8toreg32:=tregister(byte(reg)-byte(R_DI));
  791. end;
  792. function regtoreg8(reg : tregister) : tregister;
  793. begin
  794. regtoreg8:=reg32toreg8(reg);
  795. end;
  796. function regtoreg16(reg : tregister) : tregister;
  797. begin
  798. regtoreg16:=reg32toreg16(reg);
  799. end;
  800. function regtoreg32(reg : tregister) : tregister;
  801. begin
  802. regtoreg32:=reg;
  803. end;
  804. function regtoreg64(reg : tregister) : tregister;
  805. begin
  806. { to avoid warning }
  807. regtoreg64:=R_NO;
  808. end;
  809. function regsize(reg : tregister) : topsize;
  810. begin
  811. if reg in regset8bit then
  812. regsize:=S_B
  813. else if reg in regset16bit then
  814. regsize:=S_W
  815. else if reg in regset32bit then
  816. regsize:=S_L;
  817. end;
  818. procedure reset_reference(var ref : treference);
  819. begin
  820. FillChar(ref,sizeof(treference),0);
  821. end;
  822. function new_reference(base : tregister;offset : longint) : preference;
  823. var
  824. r : preference;
  825. begin
  826. new(r);
  827. FillChar(r^,sizeof(treference),0);
  828. r^.base:=base;
  829. r^.offset:=offset;
  830. new_reference:=r;
  831. end;
  832. {*****************************************************************************
  833. Instruction table
  834. *****************************************************************************}
  835. var
  836. saveexit : pointer;
  837. procedure FreeInsTabCache;{$ifndef FPC}far;{$endif}
  838. begin
  839. exitproc:=saveexit;
  840. {$ifndef NOAG386BIN}
  841. dispose(instabcache);
  842. {$endif NOAG386BIN}
  843. end;
  844. procedure BuildInsTabCache;
  845. {$ifndef NOAG386BIN}
  846. var
  847. i : longint;
  848. {$endif}
  849. begin
  850. {$ifndef NOAG386BIN}
  851. new(instabcache);
  852. FillChar(instabcache^,sizeof(tinstabcache),$ff);
  853. i:=0;
  854. while (i<InsTabEntries) do
  855. begin
  856. if InsTabCache^[InsTab[i].OPcode]=-1 then
  857. InsTabCache^[InsTab[i].OPcode]:=i;
  858. inc(i);
  859. end;
  860. {$endif NOAG386BIN}
  861. saveexit:=exitproc;
  862. exitproc:=@FreeInsTabCache;
  863. end;
  864. begin
  865. BuildInsTabCache;
  866. end.
  867. {
  868. $Log$
  869. Revision 1.2 1999-08-04 13:45:25 florian
  870. + floating point register variables !!
  871. * pairegalloc is now generated for register variables
  872. Revision 1.1 1999/08/04 00:22:58 florian
  873. * renamed i386asm and i386base to cpuasm and cpubase
  874. Revision 1.10 1999/08/02 21:28:58 florian
  875. * the main branch psub.pas is now used for
  876. newcg compiler
  877. Revision 1.9 1999/08/02 21:01:45 michael
  878. * Moved toperand type back =(
  879. Revision 1.8 1999/08/02 20:45:49 michael
  880. * Moved toperand type to aasm
  881. Revision 1.7 1999/08/02 17:17:09 florian
  882. * small changes for the new code generator
  883. Revision 1.6 1999/06/06 15:53:15 peter
  884. * suffix adding can be turned of for some tasmops in att_nosuffix array
  885. Revision 1.5 1999/05/27 19:44:34 peter
  886. * removed oldasm
  887. * plabel -> pasmlabel
  888. * -a switches to source writing automaticly
  889. * assembler readers OOPed
  890. * asmsymbol automaticly external
  891. * jumptables and other label fixes for asm readers
  892. Revision 1.4 1999/05/17 14:33:50 pierre
  893. uses heaptrc need for extrainfo with heaptrc
  894. Revision 1.3 1999/05/12 00:19:51 peter
  895. * removed R_DEFAULT_SEG
  896. * uniform float names
  897. Revision 1.2 1999/05/11 16:30:00 peter
  898. * more noag386bin defines, so tp7 can compile at least
  899. Revision 1.1 1999/05/01 13:24:23 peter
  900. * merged nasm compiler
  901. * old asm moved to oldasm/
  902. Revision 1.13 1999/04/14 09:07:43 peter
  903. * asm reader improvements
  904. Revision 1.12 1999/04/10 16:14:09 peter
  905. * fixed optimizer
  906. Revision 1.11 1999/03/31 13:55:33 peter
  907. * assembler inlining working for ag386bin
  908. Revision 1.10 1999/03/29 16:05:50 peter
  909. * optimizer working for ag386bin
  910. Revision 1.9 1999/03/26 00:01:14 peter
  911. * first things for optimizer (compiles but cycle crashes)
  912. Revision 1.8 1999/03/06 17:24:21 peter
  913. * rewritten intel parser a lot, especially reference reading
  914. * size checking added for asm parsers
  915. Revision 1.7 1999/03/02 02:56:20 peter
  916. + stabs support for binary writers
  917. * more fixes and missing updates from the previous commit :(
  918. Revision 1.6 1999/03/01 15:46:22 peter
  919. * ag386bin finally make cycles correct
  920. * prefixes are now also normal opcodes
  921. Revision 1.5 1999/02/26 00:48:29 peter
  922. * assembler writers fixed for ag386bin
  923. Revision 1.4 1999/02/25 21:03:04 peter
  924. * ag386bin updates
  925. + coff writer
  926. Revision 1.3 1999/02/22 02:44:18 peter
  927. * ag386bin doesn't use i386.pas anymore
  928. Revision 1.2 1999/02/22 02:16:03 peter
  929. * updates for ag386bin
  930. Revision 1.1 1999/02/16 17:59:38 peter
  931. + initial files
  932. }