cpubase.pas 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228
  1. {
  2. $Id$
  3. Copyright (c) 1999 by Florian Klaempfl and Peter Vreman
  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 = 1292;
  31. maxinfolen = 8;
  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_XMMREG = $00201010; { Katmai registers }
  93. OT_MEMORY = $00204000; { register number in 'basereg' }
  94. OT_MEM8 = $00204001;
  95. OT_MEM16 = $00204002;
  96. OT_MEM32 = $00204004;
  97. OT_MEM64 = $00204008;
  98. OT_MEM80 = $00204010;
  99. OT_FPUREG = $01000000; { floating point stack registers }
  100. OT_FPU0 = $01000800; { FPU stack register zero }
  101. OT_REG_SMASK = $00070000; { special register operands: these may be treated differently }
  102. { a mask for the following }
  103. OT_REG_ACCUM = $00211000; { accumulator: AL, AX or EAX }
  104. OT_REG_AL = $00211001; { REG_ACCUM | BITSxx }
  105. OT_REG_AX = $00211002; { ditto }
  106. OT_REG_EAX = $00211004; { and again }
  107. OT_REG_COUNT = $00221000; { counter: CL, CX or ECX }
  108. OT_REG_CL = $00221001; { REG_COUNT | BITSxx }
  109. OT_REG_CX = $00221002; { ditto }
  110. OT_REG_ECX = $00221004; { another one }
  111. OT_REG_DX = $00241002;
  112. OT_REG_SREG = $00081002; { any segment register }
  113. OT_REG_CS = $01081002; { CS }
  114. OT_REG_DESS = $02081002; { DS, ES, SS (non-CS 86 registers) }
  115. OT_REG_FSGS = $04081002; { FS, GS (386 extended registers) }
  116. OT_REG_CDT = $00101004; { CRn, DRn and TRn }
  117. OT_REG_CREG = $08101004; { CRn }
  118. OT_REG_CR4 = $08101404; { CR4 (Pentium only) }
  119. OT_REG_DREG = $10101004; { DRn }
  120. OT_REG_TREG = $20101004; { TRn }
  121. OT_MEM_OFFS = $00604000; { special type of EA }
  122. { simple [address] offset }
  123. OT_ONENESS = $00800000; { special type of immediate operand }
  124. { so UNITY == IMMEDIATE | ONENESS }
  125. OT_UNITY = $00802000; { for shift/rotate instructions }
  126. {Instruction flags }
  127. IF_SM = $00000001; { size match first two operands }
  128. IF_SM2 = $00000002;
  129. IF_SB = $00000004; { unsized operands can't be non-byte }
  130. IF_SW = $00000008; { unsized operands can't be non-word }
  131. IF_SD = $00000010; { unsized operands can't be nondword }
  132. IF_AR0 = $00000020; { SB, SW, SD applies to argument 0 }
  133. IF_AR1 = $00000040; { SB, SW, SD applies to argument 1 }
  134. IF_AR2 = $00000060; { SB, SW, SD applies to argument 2 }
  135. IF_ARMASK = $00000060; { mask for unsized argument spec }
  136. IF_PRIV = $00000100; { it's a privileged instruction }
  137. IF_SMM = $00000200; { it's only valid in SMM }
  138. IF_PROT = $00000400; { it's protected mode only }
  139. IF_UNDOC = $00001000; { it's an undocumented instruction }
  140. IF_FPU = $00002000; { it's an FPU instruction }
  141. IF_MMX = $00004000; { it's an MMX instruction }
  142. IF_3DNOW = $00008000; { it's a 3DNow! instruction }
  143. IF_SSE = $00010000; { it's a SSE (KNI, MMX2) instruction }
  144. IF_PMASK = $FF000000; { the mask for processor types }
  145. IF_PFMASK = $F001FF00; { the mask for disassembly "prefer" }
  146. IF_8086 = $00000000; { 8086 instruction }
  147. IF_186 = $01000000; { 186+ instruction }
  148. IF_286 = $02000000; { 286+ instruction }
  149. IF_386 = $03000000; { 386+ instruction }
  150. IF_486 = $04000000; { 486+ instruction }
  151. IF_PENT = $05000000; { Pentium instruction }
  152. IF_P6 = $06000000; { P6 instruction }
  153. IF_KATMAI = $07000000; { Katmai instructions }
  154. IF_CYRIX = $10000000; { Cyrix-specific instruction }
  155. IF_AMD = $20000000; { AMD-specific instruction }
  156. { added flags }
  157. IF_PRE = $40000000; { it's a prefix instruction }
  158. IF_PASS2 = $80000000; { if the instruction can change in a second pass }
  159. type
  160. TAsmOp=(A_None,
  161. { prefixes }
  162. A_LOCK,A_REP,A_REPE,A_REPNE,A_REPNZ,A_REPZ,
  163. A_CS,A_ES,A_DS,A_FS,A_GS,A_SS,
  164. { normal }
  165. A_AAA, A_AAD, A_AAM, A_AAS, A_ADC, A_ADD, A_AND, A_ARPL,
  166. A_BOUND, A_BSF, A_BSR, A_BSWAP, A_BT, A_BTC, A_BTR, A_BTS,
  167. A_CALL, A_CBW, A_CDQ, A_CLC, A_CLD, A_CLI, A_CLTS, A_CMC, A_CMP,
  168. A_CMPSB, A_CMPSD, A_CMPSW, A_CMPXCHG, A_CMPXCHG486, A_CMPXCHG8B,
  169. A_CPUID, A_CWD, A_CWDE, A_DAA, A_DAS, A_DEC, A_DIV,
  170. A_EMMS, A_ENTER, A_EQU, A_F2XM1, A_FABS,
  171. A_FADD, A_FADDP, A_FBLD, A_FBSTP, A_FCHS, A_FCLEX, A_FCMOVB,
  172. A_FCMOVBE, A_FCMOVE, A_FCMOVNB, A_FCMOVNBE, A_FCMOVNE,
  173. A_FCMOVNU, A_FCMOVU, A_FCOM, A_FCOMI, A_FCOMIP, A_FCOMP,
  174. A_FCOMPP, A_FCOS, A_FDECSTP, A_FDISI, A_FDIV, A_FDIVP, A_FDIVR,
  175. A_FDIVRP, A_FEMMS,
  176. A_FENI, A_FFREE, A_FIADD, A_FICOM, A_FICOMP, A_FIDIV,
  177. A_FIDIVR, A_FILD, A_FIMUL, A_FINCSTP, A_FINIT, A_FIST, A_FISTP,
  178. A_FISUB, A_FISUBR, A_FLD, A_FLD1, A_FLDCW, A_FLDENV, A_FLDL2E,
  179. A_FLDL2T, A_FLDLG2, A_FLDLN2, A_FLDPI, A_FLDZ, A_FMUL, A_FMULP,
  180. A_FNCLEX, A_FNDISI, A_FNENI, A_FNINIT, A_FNOP, A_FNSAVE,
  181. A_FNSTCW, A_FNSTENV, A_FNSTSW, A_FPATAN, A_FPREM, A_FPREM1,
  182. A_FPTAN, A_FRNDINT, A_FRSTOR, A_FSAVE, A_FSCALE, A_FSETPM,
  183. A_FSIN, A_FSINCOS, A_FSQRT, A_FST, A_FSTCW, A_FSTENV, A_FSTP,
  184. A_FSTSW, A_FSUB, A_FSUBP, A_FSUBR, A_FSUBRP, A_FTST, A_FUCOM,
  185. A_FUCOMI, A_FUCOMIP, A_FUCOMP, A_FUCOMPP, A_FWAIT,A_FXAM, A_FXCH,
  186. A_FXTRACT, A_FYL2X, A_FYL2XP1, A_HLT, A_IBTS, A_ICEBP, A_IDIV,
  187. A_IMUL, A_IN, A_INC, A_INSB, A_INSD, A_INSW, A_INT,
  188. A_INT01, A_INT1, A_INT03, A_INT3, A_INTO, A_INVD, A_INVLPG, A_IRET,
  189. A_IRETD, A_IRETW, A_JCXZ, A_JECXZ, A_JMP, A_LAHF, A_LAR, A_LDS,
  190. A_LEA, A_LEAVE, A_LES, A_LFS, A_LGDT, A_LGS, A_LIDT, A_LLDT,
  191. A_LMSW, A_LOADALL, A_LOADALL286, A_LODSB, A_LODSD, A_LODSW,
  192. A_LOOP, A_LOOPE, A_LOOPNE, A_LOOPNZ, A_LOOPZ, A_LSL, A_LSS,
  193. A_LTR, A_MOV, A_MOVD, A_MOVQ, A_MOVSB, A_MOVSD, A_MOVSW,
  194. A_MOVSX, A_MOVZX, A_MUL, A_NEG, A_NOP, A_NOT, A_OR, A_OUT,
  195. A_OUTSB, A_OUTSD, A_OUTSW, A_PACKSSDW, A_PACKSSWB, A_PACKUSWB,
  196. A_PADDB, A_PADDD, A_PADDSB, A_PADDSIW, A_PADDSW, A_PADDUSB,
  197. A_PADDUSW, A_PADDW, A_PAND, A_PANDN, A_PAVEB,
  198. A_PAVGUSB, A_PCMPEQB, A_PCMPEQD, A_PCMPEQW, A_PCMPGTB, A_PCMPGTD,
  199. A_PCMPGTW, A_PDISTIB,
  200. A_PF2ID, A_PFACC, A_PFADD, A_PFCMPEQ, A_PFCMPGE, A_PFCMPGT,
  201. A_PFMAX, A_PFMIN, A_PFMUL, A_PFRCP, A_PFRCPIT1, A_PFRCPIT2,
  202. A_PFRSQIT1, A_PFRSQRT, A_PFSUB, A_PFSUBR, A_PI2FD,
  203. A_PMACHRIW, A_PMADDWD, A_PMAGW, A_PMULHRIW, A_PMULHRWA,
  204. A_PMULHRWC, A_PMULHW, A_PMULLW, A_PMVGEZB, A_PMVLZB, A_PMVNZB,
  205. A_PMVZB, A_POP, A_POPA, A_POPAD, A_POPAW, A_POPF, A_POPFD,
  206. A_POPFW, A_POR, A_PREFETCH, A_PREFETCHW,
  207. A_PSLLD, A_PSLLQ, A_PSLLW, A_PSRAD, A_PSRAW,
  208. A_PSRLD, A_PSRLQ, A_PSRLW, A_PSUBB, A_PSUBD, A_PSUBSB,
  209. A_PSUBSIW, A_PSUBSW, A_PSUBUSB, A_PSUBUSW, A_PSUBW, A_PUNPCKHBW,
  210. A_PUNPCKHDQ, A_PUNPCKHWD, A_PUNPCKLBW, A_PUNPCKLDQ, A_PUNPCKLWD,
  211. A_PUSH, A_PUSHA, A_PUSHAD, A_PUSHAW, A_PUSHF, A_PUSHFD,
  212. A_PUSHFW, A_PXOR, A_RCL, A_RCR, A_RDSHR, A_RDMSR, A_RDPMC, A_RDTSC,
  213. A_RESB, A_RET, A_RETF, A_RETN,
  214. A_ROL, A_ROR, A_RSDC, A_RSLDT, A_RSM, A_SAHF, A_SAL, A_SALC, A_SAR, A_SBB,
  215. A_SCASB, A_SCASD, A_SCASW, A_SGDT, A_SHL, A_SHLD, A_SHR, A_SHRD,
  216. A_SIDT, A_SLDT, A_SMI, A_SMINT, A_SMINTOLD, A_SMSW, A_STC, A_STD, A_STI, A_STOSB,
  217. A_STOSD, A_STOSW, A_STR, A_SUB, A_SVDC, A_SVLDT, A_SVTS, A_SYSCALL, A_SYSENTER,
  218. A_SYSEXIT, A_SYSRET, A_TEST, A_UD1, A_UD2, A_UMOV, A_VERR, A_VERW,
  219. A_WAIT, A_WBINVD, A_WRSHR, A_WRMSR, A_XADD, A_XBTS, A_XCHG, A_XLAT, A_XLATB,
  220. A_XOR, A_CMOVcc, A_Jcc, A_SETcc,
  221. A_ADDPS, A_ADDSS, A_ANDNPS, A_ANDPS, A_CMPEQPS, A_CMPEQSS, A_CMPLEPS,
  222. A_CMPLESS, A_CMPLTPS, A_CMPLTSS, A_CMPNEQPS, A_CMPNEQSS, A_CMPNLEPS,
  223. A_CMPNLESS, A_CMPNLTPS, A_CMPNLTSS, A_CMPORDPS, A_CMPORDSS, A_CMPUNORDPS, A_CMPUNORDSS,
  224. A_CMPPS, A_CMPSS, A_COMISS, A_CVTPI2PS, A_CVTPS2PI, A_CVTSI2SS, A_CVTSS2SI,
  225. A_CVTTPS2PI, A_CVTTSS2SI, A_DIVPS, A_DIVSS, A_LDMXCSR, A_MAXPS, A_MAXSS, A_MINPS,
  226. A_MINSS, A_MOVAPS, A_MOVHPS, A_MOVLHPS, A_MOVLPS, A_MOVHLPS, A_MOVMSKPS,
  227. A_MOVNTPS, A_MOVSS, A_MOVUPS, A_MULPS, A_MULSS, A_ORPS, A_RCPPS, A_RCPSS,
  228. A_RSQRTPS, A_RSQRTSS, A_SHUFPS, A_SQRTPS, A_SQRTSS, A_STMXCSR, A_SUBPS, A_SUBSS,
  229. A_UCOMISS, A_UNPCKHPS, A_UNPCKLPS, A_XORPS, A_FXRSTOR, A_FXSAVE, A_PREFETCHNTA,
  230. A_PREFETCHT0, A_PREFETCHT1,A_PREFETCHT2,
  231. A_SFENCE, A_MASKMOVQ, A_MOVNTQ, A_PAVGB, A_PAVGW, A_PEXTRW, A_PINSRW, A_PMAXSW,
  232. A_PMAXUB, A_PMINSW, A_PMINUB, A_PMOVMSKB, A_PMULHUW, A_PSADBW, A_PSHUFW
  233. );
  234. op2strtable=array[tasmop] of string[10];
  235. const
  236. firstop = low(tasmop);
  237. lastop = high(tasmop);
  238. AsmPrefixes = 6;
  239. AsmPrefix : array[0..AsmPrefixes-1] of TasmOP =(
  240. A_LOCK,A_REP,A_REPE,A_REPNE,A_REPNZ,A_REPZ
  241. );
  242. AsmOverrides = 6;
  243. AsmOverride : array[0..AsmOverrides-1] of TasmOP =(
  244. A_CS,A_ES,A_DS,A_FS,A_GS,A_SS
  245. );
  246. {$ifdef INTELOP}
  247. int_op2str:op2strtable=('<none>',
  248. { prefixes }
  249. 'lock','rep','repe','repne','repnz','repz',
  250. 'segcs','seges','segds','segfs','seggs','segss',
  251. { normal }
  252. 'aaa','aad','aam','aas','adc','add','and','arpl',
  253. 'bound','bsf','bsr','bswap','bt','btc','btr','bts',
  254. 'call','cbw','cdq','clc','cld','cli','clts','cmc','cmp',
  255. 'cmpsb','cmpsd','cmpsw','cmpxchg','cmpxchg486','cmpxchg8b',
  256. 'cpuid','cwd','cwde','daa','das','dec','div','emms',
  257. 'enter','equ','f2xm1','fabs',
  258. 'fadd','faddp','fbld','fbstp','fchs','fclex','fcmovb',
  259. 'fcmovbe','fcmove','fcmovnb','fcmovnbe','fcmovne',
  260. 'fcmovnu','fcmovu','fcom','fcomi','fcomip','fcomp',
  261. 'fcompp','fcos','fdecstp','fdisi','fdiv','fdivp','fdivr',
  262. 'fdivrp',
  263. 'femms',
  264. 'feni','ffree','fiadd','ficom','ficomp','fidiv',
  265. 'fidivr','fild','fimul','fincstp','finit','fist','fistp',
  266. 'fisub','fisubr','fld','fld1','fldcw','fldenv','fldl2e',
  267. 'fldl2t','fldlg2','fldln2','fldpi','fldz','fmul','fmulp',
  268. 'fnclex','fndisi','fneni','fninit','fnop','fnsave',
  269. 'fnstcw','fnstenv','fnstsw','fpatan','fprem','fprem1',
  270. 'fptan','frndint','frstor','fsave','fscale','fsetpm',
  271. 'fsin','fsincos','fsqrt','fst','fstcw','fstenv','fstp',
  272. 'fstsw','fsub','fsubp','fsubr','fsubrp','ftst','fucom',
  273. 'fucomi','fucomip','fucomp','fucompp','fwait','fxam','fxch',
  274. 'fxtract','fyl2x','fyl2xp1','hlt','ibts','icebp','idiv',
  275. 'imul','in','inc','insb','insd','insw','int',
  276. 'int01','int1','int03','int3','into','invd','invlpg','iret',
  277. 'iretd','iretw','jcxz','jecxz','jmp','lahf','lar','lds',
  278. 'lea','leave','les','lfs','lgdt','lgs','lidt','lldt',
  279. 'lmsw','loadall','loadall286','lodsb','lodsd','lodsw',
  280. 'loop','loope','loopne','loopnz','loopz','lsl','lss',
  281. 'ltr','mov','movd','movq','movsb','movsd','movsw',
  282. 'movsx','movzx','mul','neg','nop','not','or','out',
  283. 'outsb','outsd','outsw','packssdw','packsswb','packuswb',
  284. 'paddb','paddd','paddsb','paddsiw','paddsw','paddusb',
  285. 'paddusw','paddw','pand','pandn','paveb',
  286. 'pavgusb','pcmpeqb',
  287. 'pcmpeqd','pcmpeqw','pcmpgtb','pcmpgtd','pcmpgtw',
  288. 'pdistib',
  289. 'pf2id','pfacc','pfadd','pfcmpeq','pfcmpge','pfcmpgt',
  290. 'pfmax','pfmin','pfmul','pfrcp','pfrcpit1','pfrcpit2',
  291. 'pfrsqit1','pfrsqrt','pfsub','pfsubr','pi2fd',
  292. 'pmachriw','pmaddwd','pmagw','pmulhriw','pmulhrwa','pmulhrwc',
  293. 'pmulhw','pmullw','pmvgezb','pmvlzb','pmvnzb',
  294. 'pmvzb','pop','popa','popad','popaw','popf','popfd',
  295. 'popfw','por',
  296. 'prefetch','prefetchw','pslld','psllq','psllw','psrad','psraw',
  297. 'psrld','psrlq','psrlw','psubb','psubd','psubsb',
  298. 'psubsiw','psubsw','psubusb','psubusw','psubw','punpckhbw',
  299. 'punpckhdq','punpckhwd','punpcklbw','punpckldq','punpcklwd',
  300. 'push','pusha','pushad','pushaw','pushf','pushfd',
  301. 'pushfw','pxor','rcl','rcr','rdshr','rdmsr','rdpmc','rdtsc',
  302. 'resb','ret','retf','retn',
  303. 'rol','ror','rsdc','rsldt','rsm','sahf','sal','salc','sar','sbb',
  304. 'scasb','scasd','scasw','sgdt','shl','shld','shr','shrd',
  305. 'sidt','sldt','smi','smint','smintold','smsw','stc','std','sti','stosb',
  306. 'stosd','stosw','str','sub','svdc','svldt','svts','syscall','sysenter',
  307. 'sysexit','sysret','test','ud1','ud2','umov','verr','verw',
  308. 'wait','wbinvd','wrshr','wrmsr','xadd','xbts','xchg','xlat','xlatb',
  309. 'xor','cmov','j','set',
  310. 'addps','addss','andnps','andps','cmpeqps','cmpeqss','cmpleps','cmpless','cmpltps',
  311. 'cmpltss','cmpneqps','cmpneqss','cmpnleps','cmpnless','cmpnltps','cmpnltss',
  312. 'cmpordps','cmpordss','cmpunordps','cmpunordss','cmpps','cmpss','comiss','cvtpi2ps','cvtps2pi',
  313. 'cvtsi2ss','cvtss2si','cvttps2pi','cvttss2si','divps','divss','ldmxcsr','maxps',
  314. 'maxss','minps','minss','movaps','movhps','movlhps','movlps','movhlps','movmskps',
  315. 'movntps','movss','movups','mulps','mulss','orps','rcpps','rcpss','rsqrtps','rsqrtss',
  316. 'shufps','sqrtps','sqrtss','stmxcsr','subps','subss','ucomiss','unpckhps','unpcklps',
  317. 'xorps','fxrstor','fxsave','prefetchnta','prefetcht0','prefetcht1','prefetcht2',
  318. 'sfence','maskmovq','movntq','pavgb','pavgw','pextrw','pinsrw','pmaxsw','pmaxub',
  319. 'pminsw','pminub','pmovmskb','pmulhuw','psadbw','pshufw'
  320. );
  321. {$endif INTELOP}
  322. {$ifdef ATTOP}
  323. att_op2str:op2strtable=('<none>',
  324. { prefixes }
  325. 'lock','rep','repe','repne','repnz','repz',
  326. 'cs','es','ds','fs','gs','ss',
  327. { normal }
  328. 'aaa','aad','aam','aas','adc','add','and','arpl',
  329. 'bound','bsf','bsr','bswap','bt','btc','btr','bts',
  330. 'call','cbtw','cltd','clc','cld','cli','clts','cmc','cmp',
  331. 'cmpsb','cmpsl','cmpsw','cmpxchg','cmpxchg486','cmpxchg8b',
  332. 'cpuid','cwtd','cwtl','daa','das','dec','div',
  333. 'emms','enter','equ','f2xm1','fabs',
  334. 'fadd','faddp','fbld','fbstp','fchs','fclex','fcmovb',
  335. 'fcmovbe','fcmove','fcmovnb','fcmovnbe','fcmovne',
  336. 'fcmovnu','fcmovu','fcom','fcomi','fcomip','fcomp',
  337. 'fcompp','fcos','fdecstp','fdisi','fdiv','fdivp','fdivr',
  338. 'fdivrp','femms',
  339. 'feni','ffree','fiadd','ficom','ficomp','fidiv',
  340. 'fidivr','fild','fimul','fincstp','finit','fist','fistp',
  341. 'fisub','fisubr','fld','fld1','fldcw','fldenv','fldl2e',
  342. 'fldl2t','fldlg2','fldln2','fldpi','fldz','fmul','fmulp',
  343. 'fnclex','fndisi','fneni','fninit','fnop','fnsave',
  344. 'fnstcw','fnstenv','fnstsw','fpatan','fprem','fprem1',
  345. 'fptan','frndint','frstor','fsave','fscale','fsetpm',
  346. 'fsin','fsincos','fsqrt','fst','fstcw','fstenv','fstp',
  347. 'fstsw','fsub','fsubp','fsubr','fsubrp','ftst','fucom',
  348. 'fucomi','fucomip','fucomp','fucompp','fwait','fxam','fxch',
  349. 'fxtract','fyl2x','fyl2xp1','hlt','ibts','icebp','idiv',
  350. 'imul','in','inc','insb','insl','insw','int',
  351. 'int01','int1','int03','int3','into','invd','invlpg','iret',
  352. 'iretd','iretw','jcxz','jecxz','jmp','lahf','lar','lds',
  353. 'lea','leave','les','lfs','lgdt','lgs','lidt','lldt',
  354. 'lmsw','loadall','loadall286','lodsb','lodsl','lodsw',
  355. 'loop','loope','loopne','loopnz','loopz','lsl','lss',
  356. 'ltr','mov','movd','movq','movsb','movsl','movsw',
  357. 'movs','movz','mul','neg','nop','not','or','out',
  358. 'outsb','outsl','outsw','packssd','packssw','packusw',
  359. 'paddb','paddd','paddsb','paddsiw','paddsw','paddusb',
  360. 'paddusw','paddw','pand','pandn','paveb',
  361. 'pavgusb','pcmpeqb',
  362. 'pcmpeqd','pcmpeqw','pcmpgtb','pcmpgtd','pcmpgtw',
  363. 'pdistib',
  364. 'pf2id','pfacc','pfadd','pfcmpeq','pfcmpge','pfcmpgt',
  365. 'pfmax','pfmin','pfmul','pfrcp','pfrcpit1','pfrcpit2',
  366. 'pfrsqit1','pfrsqrt','pfsub','pfsubr','pi2fd',
  367. 'pmachriw','pmaddwd','pmagw','pmulhriw','pmulhrwa','pmulhrwc',
  368. 'pmulhw','pmullw','pmvgezb','pmvlzb','pmvnzb',
  369. 'pmvzb','pop','popa','popal','popaw','popf','popfl',
  370. 'popfw','por',
  371. 'prefetch','prefetchw','pslld','psllq','psllw','psrad','psraw',
  372. 'psrld','psrlq','psrlw','psubb','psubd','psubsb',
  373. 'psubsiw','psubsw','psubusb','psubusw','psubw','punpckhbw',
  374. 'punpckhdq','punpckhwd','punpcklbw','punpckldq','punpcklwd',
  375. 'push','pusha','pushal','pushaw','pushf','pushfl',
  376. 'pushfw','pxor','rcl','rcr','rdshr','rdmsr','rdpmc','rdtsc',
  377. 'resb','ret','retf','retn',
  378. 'rol','ror','rsdc','rsldt','rsm','sahf','sal','salc','sar','sbb',
  379. 'scasb','scasl','scasw','sgdt','shl','shld','shr','shrd',
  380. 'sidt','sldt','smi','smint','smintold','smsw','stc','std','sti','stosb',
  381. 'stosl','stosw','str','sub','svdc','svldt','svts','syscall','sysenter',
  382. 'sysexit','sysret','test','ud1','ud2','umov','verr','verw',
  383. 'wait','wbinvd','wrshr','wrmsr','xadd','xbts','xchg','xlat','xlatb',
  384. 'xor','cmov','j','set',
  385. 'addps','addss','andnps','andps','cmpeqps','cmpeqss','cmpleps','cmpless','cmpltps',
  386. 'cmpltss','cmpneqps','cmpneqss','cmpnleps','cmpnless','cmpnltps','cmpnltss',
  387. 'cmpordps','cmpordss','cmpunordps','cmpunordss','cmpps','cmpss','comiss','cvtpi2ps','cvtps2pi',
  388. 'cvtsi2ss','cvtss2si','cvttps2pi','cvttss2si','divps','divss','ldmxcsr','maxps',
  389. 'maxss','minps','minss','movaps','movhps','movlhps','movlps','movhlps','movmskps',
  390. 'movntps','movss','movups','mulps','mulss','orps','rcpps','rcpss','rsqrtps','rsqrtss',
  391. 'shufps','sqrtps','sqrtss','stmxcsr','subps','subss','ucomiss','unpckhps','unpcklps',
  392. 'xorps','fxrstor','fxsave','prefetchnta','prefetcht0','prefetcht1','prefetcht2',
  393. 'sfence','maskmovq','movntq','pavgb','pavgw','pextrw','pinsrw','pmaxsw','pmaxub',
  394. 'pminsw','pminub','pmovmskb','pmulhuw','psadbw','pshufw'
  395. );
  396. att_nosuffix:array[tasmop] of boolean=(
  397. { 0 }
  398. false,false,false,false,false,false,false,false,false,false,
  399. false,false,false,false,false,false,false,false,false,false,
  400. false,false,false,false,false,false,false,false,false,false,
  401. false,false,false,false,false,false,false,false,false,false,
  402. false,false,false,false,false,false,false,false,false,false,
  403. false,false,false,false,false,false,false,false,false,false,
  404. false,false,false,false,false,false,false,false,false,false,
  405. false,false,false,false,false,false,false,false,false,false,
  406. false,false,false,false,false,false,false,false,false,false,
  407. false,false,false,false,false,false,false,false,false,false,
  408. { 100 }
  409. false,false,false,false,false,false,false,false,false,false,
  410. false,false,false,false,false,false,false,false,false,false,
  411. false,false,false,false,false,false,false,false,false,false,
  412. false,false,false,false,false,false,false,false,false,false,
  413. false,false,false,false,false,false,false,false,false,false,
  414. false,false,false,false,false,false,false,false,false,false,
  415. false,false,false,false,false,false,false,false,false,false,
  416. false,false,false,false,false,false,false,false,false,false,
  417. false,false,false,false,false,false,false,false,false,false,
  418. false,false,false,false,false,false,false,false,false,false,
  419. { 200 }
  420. false,false,true,true,true,true,true,false,false,false,
  421. false,false,false,false,false,false,false,false,true,true,
  422. true,true,true,true,true,true,true,true,true,true,
  423. true,true,true,true,true,true,true,true,true,true,
  424. true,true,true,true,true,true,true,true,true,true,
  425. true,true,true,true,true,true,true,true,true,true,
  426. true,true,true,true,true,true,true,true,false,false,
  427. false,false,false,false,false,false,true,true,true,true,
  428. true,true,true,true,true,true,true,true,true,true,
  429. true,true,true,true,true,true,true,true,true,
  430. { 300 }
  431. true,false,false,true,true,false,true,true,true,false,false,
  432. false,false,false,false,false,false,false,false,false,false,
  433. false,false,false,false,false,false,false,false,false,false,
  434. false,false,false,false,false,false,false,false,false,false,
  435. false,false,false,false,false,false,false,false,false,false,
  436. false,false,false,false,false,false,false,false,false,false,
  437. false,false,false,false,false,false,false,false,false,false,
  438. false,false,false,false,false,false,false,true,true,true,
  439. true,true,true,true,true,true,true,true,true,true,
  440. true,true,true,true,true,true,true,true,true,true,
  441. { 400 }
  442. true,true,true,true,true,true,true,true,true,true,
  443. true,true,true,true,true,true,true,true,true,true,
  444. true,true,true,true,true,true,true,true,true,true,
  445. true,true,true,true,true,true,true,true,true,true,
  446. true,true,true,true,true,true,true,true,true,true,
  447. true,true,true,true,true,true,true,true,true,true
  448. );
  449. {$endif ATTOP}
  450. {*****************************************************************************
  451. Operand Sizes
  452. *****************************************************************************}
  453. type
  454. topsize = (S_NO,
  455. S_B,S_W,S_L,S_BW,S_BL,S_WL,
  456. S_IS,S_IL,S_IQ,
  457. S_FS,S_FL,S_FX,S_D,S_Q,S_FV
  458. );
  459. const
  460. { Intel style operands ! }
  461. opsize_2_type:array[0..2,topsize] of longint=(
  462. (OT_NONE,
  463. OT_BITS8,OT_BITS16,OT_BITS32,OT_BITS16,OT_BITS32,OT_BITS32,
  464. OT_BITS16,OT_BITS32,OT_BITS64,
  465. OT_BITS32,OT_BITS64,OT_BITS80,OT_BITS64,OT_BITS64,OT_BITS64
  466. ),
  467. (OT_NONE,
  468. OT_BITS8,OT_BITS16,OT_BITS32,OT_BITS8,OT_BITS8,OT_BITS16,
  469. OT_BITS16,OT_BITS32,OT_BITS64,
  470. OT_BITS32,OT_BITS64,OT_BITS80,OT_BITS64,OT_BITS64,OT_BITS64
  471. ),
  472. (OT_NONE,
  473. OT_BITS8,OT_BITS16,OT_BITS32,OT_NONE,OT_NONE,OT_NONE,
  474. OT_BITS16,OT_BITS32,OT_BITS64,
  475. OT_BITS32,OT_BITS64,OT_BITS80,OT_BITS64,OT_BITS64,OT_BITS64
  476. )
  477. );
  478. {$ifdef ATTOP}
  479. att_opsize2str : array[topsize] of string[2] = ('',
  480. 'b','w','l','bw','bl','wl',
  481. 's','l','q',
  482. 's','l','t','d','q','v'
  483. );
  484. {$endif}
  485. {*****************************************************************************
  486. Conditions
  487. *****************************************************************************}
  488. type
  489. TAsmCond=(C_None,
  490. C_A,C_AE,C_B,C_BE,C_C,C_E,C_G,C_GE,C_L,C_LE,C_NA,C_NAE,
  491. C_NB,C_NBE,C_NC,C_NE,C_NG,C_NGE,C_NL,C_NLE,C_NO,C_NP,
  492. C_NS,C_NZ,C_O,C_P,C_PE,C_PO,C_S,C_Z
  493. );
  494. const
  495. cond2str:array[TAsmCond] of string[3]=('',
  496. 'a','ae','b','be','c','e','g','ge','l','le','na','nae',
  497. 'nb','nbe','nc','ne','ng','nge','nl','nle','no','np',
  498. 'ns','nz','o','p','pe','po','s','z'
  499. );
  500. inverse_cond:array[TAsmCond] of TAsmCond=(C_None,
  501. C_NA,C_NAE,C_NB,C_NBE,C_NC,C_NE,C_NG,C_NGE,C_NL,C_NLE,C_A,C_AE,
  502. C_B,C_BE,C_C,C_E,C_G,C_GE,C_L,C_LE,C_O,C_P,
  503. C_S,C_Z,C_NO,C_NP,C_NP,C_P,C_NS,C_NZ
  504. );
  505. const
  506. CondAsmOps=3;
  507. CondAsmOp:array[0..CondAsmOps-1] of TasmOp=(
  508. A_CMOVcc, A_Jcc, A_SETcc
  509. );
  510. CondAsmOpStr:array[0..CondAsmOps-1] of string[4]=(
  511. 'CMOV','J','SET'
  512. );
  513. {*****************************************************************************
  514. Registers
  515. *****************************************************************************}
  516. type
  517. { enumeration for registers, don't change the order }
  518. { it's used by the register size conversions }
  519. tregister = (R_NO,
  520. R_EAX,R_ECX,R_EDX,R_EBX,R_ESP,R_EBP,R_ESI,R_EDI,
  521. R_AX,R_CX,R_DX,R_BX,R_SP,R_BP,R_SI,R_DI,
  522. R_AL,R_CL,R_DL,R_BL,R_AH,R_CH,R_BH,R_DH,
  523. R_CS,R_DS,R_ES,R_SS,R_FS,R_GS,
  524. R_ST,R_ST0,R_ST1,R_ST2,R_ST3,R_ST4,R_ST5,R_ST6,R_ST7,
  525. R_DR0,R_DR1,R_DR2,R_DR3,R_DR6,R_DR7,
  526. R_CR0,R_CR2,R_CR3,R_CR4,
  527. R_TR3,R_TR4,R_TR5,R_TR6,R_TR7,
  528. R_MM0,R_MM1,R_MM2,R_MM3,R_MM4,R_MM5,R_MM6,R_MM7,
  529. R_XMM0,R_XMM1,R_XMM2,R_XMM3,R_XMM4,R_XMM5,R_XMM6,R_XMM7
  530. );
  531. tregisterset = set of tregister;
  532. reg2strtable = array[tregister] of string[6];
  533. const
  534. firstreg = low(tregister);
  535. lastreg = high(tregister);
  536. firstsreg = R_CS;
  537. lastsreg = R_GS;
  538. regset8bit : tregisterset = [R_AL..R_DH];
  539. regset16bit : tregisterset = [R_AX..R_DI,R_CS..R_SS];
  540. regset32bit : tregisterset = [R_EAX..R_EDI];
  541. { Convert reg to opsize }
  542. reg_2_opsize:array[firstreg..lastreg] of topsize = (S_NO,
  543. S_L,S_L,S_L,S_L,S_L,S_L,S_L,S_L,
  544. S_W,S_W,S_W,S_W,S_W,S_W,S_W,S_W,
  545. S_B,S_B,S_B,S_B,S_B,S_B,S_B,S_B,
  546. S_W,S_W,S_W,S_W,S_W,S_W,
  547. S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,
  548. S_L,S_L,S_L,S_L,S_L,S_L,
  549. S_L,S_L,S_L,S_L,
  550. S_L,S_L,S_L,S_L,S_L,
  551. S_D,S_D,S_D,S_D,S_D,S_D,S_D,S_D,
  552. S_D,S_D,S_D,S_D,S_D,S_D,S_D,S_D
  553. );
  554. { Convert reg to operand type }
  555. reg_2_type:array[firstreg..lastreg] of longint = (OT_NONE,
  556. OT_REG_EAX,OT_REG_ECX,OT_REG32,OT_REG32,OT_REG32,OT_REG32,OT_REG32,OT_REG32,
  557. OT_REG_AX,OT_REG_CX,OT_REG_DX,OT_REG16,OT_REG16,OT_REG16,OT_REG16,OT_REG16,
  558. OT_REG_AL,OT_REG_CL,OT_REG8,OT_REG8,OT_REG8,OT_REG8,OT_REG8,OT_REG8,
  559. OT_REG_CS,OT_REG_DESS,OT_REG_DESS,OT_REG_DESS,OT_REG_FSGS,OT_REG_FSGS,
  560. OT_FPU0,OT_FPU0,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,
  561. OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,
  562. OT_REG_CREG,OT_REG_CREG,OT_REG_CREG,OT_REG_CR4,
  563. OT_REG_TREG,OT_REG_TREG,OT_REG_TREG,OT_REG_TREG,OT_REG_TREG,
  564. OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,
  565. OT_XMMREG,OT_XMMREG,OT_XMMREG,OT_XMMREG,OT_XMMREG,OT_XMMREG,OT_XMMREG,OT_XMMREG
  566. );
  567. {$ifdef INTELOP}
  568. int_reg2str : reg2strtable = ('',
  569. 'eax','ecx','edx','ebx','esp','ebp','esi','edi',
  570. 'ax','cx','dx','bx','sp','bp','si','di',
  571. 'al','cl','dl','bl','ah','ch','bh','dh',
  572. 'cs','ds','es','ss','fs','gs',
  573. 'st','st(0)','st(1)','st(2)','st(3)','st(4)','st(5)','st(6)','st(7)',
  574. 'dr0','dr1','dr2','dr3','dr6','dr7',
  575. 'cr0','cr2','cr3','cr4',
  576. 'tr3','tr4','tr5','tr6','tr7',
  577. 'mm0','mm1','mm2','mm3','mm4','mm5','mm6','mm7',
  578. 'xmm0','xmm1','xmm2','xmm3','xmm4','xmm5','xmm6','xmm7'
  579. );
  580. int_nasmreg2str : reg2strtable = ('',
  581. 'eax','ecx','edx','ebx','esp','ebp','esi','edi',
  582. 'ax','cx','dx','bx','sp','bp','si','di',
  583. 'al','cl','dl','bl','ah','ch','bh','dh',
  584. 'cs','ds','es','ss','fs','gs',
  585. 'st0','st0','st1','st2','st3','st4','st5','st6','st7',
  586. 'dr0','dr1','dr2','dr3','dr6','dr7',
  587. 'cr0','cr2','cr3','cr4',
  588. 'tr3','tr4','tr5','tr6','tr7',
  589. 'mm0','mm1','mm2','mm3','mm4','mm5','mm6','mm7',
  590. 'xmm0','xmm1','xmm2','xmm3','xmm4','xmm5','xmm6','xmm7'
  591. );
  592. {$endif}
  593. {$ifdef ATTREG}
  594. att_reg2str : reg2strtable = ('',
  595. '%eax','%ecx','%edx','%ebx','%esp','%ebp','%esi','%edi',
  596. '%ax','%cx','%dx','%bx','%sp','%bp','%si','%di',
  597. '%al','%cl','%dl','%bl','%ah','%ch','%bh','%dh',
  598. '%cs','%ds','%es','%ss','%fs','%gs',
  599. '%st','%st(0)','%st(1)','%st(2)','%st(3)','%st(4)','%st(5)','%st(6)','%st(7)',
  600. '%dr0','%dr1','%dr2','%dr3','%dr6','%dr7',
  601. '%cr0','%cr2','%cr3','%cr4',
  602. '%tr3','%tr4','%tr5','%tr6','%tr7',
  603. '%mm0','%mm1','%mm2','%mm3','%mm4','%mm5','%mm6','%mm7',
  604. '%xmm0','%xmm1','%xmm2','%xmm3','%xmm4','%xmm5','%xmm6','%xmm7'
  605. );
  606. {$endif ATTREG}
  607. {*****************************************************************************
  608. Flags
  609. *****************************************************************************}
  610. type
  611. 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);
  612. const
  613. { arrays for boolean location conversions }
  614. flag_2_cond : array[TResFlags] of TAsmCond =
  615. (C_E,C_NE,C_G,C_L,C_GE,C_LE,C_C,C_NC,C_A,C_AE,C_B,C_BE);
  616. {*****************************************************************************
  617. Reference
  618. *****************************************************************************}
  619. type
  620. trefoptions=(ref_none,ref_parafixup,ref_localfixup,ref_selffixup);
  621. { immediate/reference record }
  622. preference = ^treference;
  623. treference = packed record
  624. is_immediate : boolean; { is this used as reference or immediate }
  625. segment,
  626. base,
  627. index : tregister;
  628. scalefactor : byte;
  629. offset : longint;
  630. symbol : pasmsymbol;
  631. offsetfixup : longint;
  632. options : trefoptions;
  633. {$ifdef newcg}
  634. alignment : byte;+
  635. {$endif newcg}
  636. end;
  637. {*****************************************************************************
  638. Operands
  639. *****************************************************************************}
  640. { Types of operand }
  641. toptype=(top_none,top_reg,top_ref,top_const,top_symbol);
  642. toper=record
  643. ot : longint;
  644. case typ : toptype of
  645. top_none : ();
  646. top_reg : (reg:tregister);
  647. top_ref : (ref:preference);
  648. top_const : (val:longint);
  649. top_symbol : (sym:pasmsymbol;symofs:longint);
  650. end;
  651. {*****************************************************************************
  652. Generic Location
  653. *****************************************************************************}
  654. type
  655. TLoc=(
  656. LOC_INVALID, { added for tracking problems}
  657. LOC_FPU, { FPU stack }
  658. LOC_REGISTER, { in a processor register }
  659. LOC_MEM, { in memory }
  660. LOC_REFERENCE, { like LOC_MEM, but lvalue }
  661. LOC_JUMP, { boolean results only, jump to false or true label }
  662. LOC_FLAGS, { boolean results only, flags are set }
  663. LOC_CREGISTER, { Constant register which shouldn't be modified }
  664. LOC_MMXREGISTER, { MMX register }
  665. LOC_CMMXREGISTER,{ Constant MMX register }
  666. LOC_CFPUREGISTER { if it is a FPU register variable on the fpu stack }
  667. );
  668. plocation = ^tlocation;
  669. tlocation = packed record
  670. case loc : tloc of
  671. LOC_MEM,LOC_REFERENCE : (reference : treference);
  672. LOC_FPU : ();
  673. LOC_JUMP : ();
  674. LOC_FLAGS : (resflags : tresflags);
  675. LOC_INVALID : ();
  676. { it's only for better handling }
  677. LOC_MMXREGISTER : (mmxreg : tregister);
  678. { segment in reference at the same place as in loc_register }
  679. LOC_REGISTER,LOC_CREGISTER : (
  680. case longint of
  681. 1 : (register,segment,registerhigh : tregister);
  682. { overlay a registerlow }
  683. 2 : (registerlow : tregister);
  684. );
  685. end;
  686. {*****************************************************************************
  687. Constants
  688. *****************************************************************************}
  689. const
  690. general_registers = [R_EAX,R_EBX,R_ECX,R_EDX];
  691. intregs = general_registers;
  692. fpuregs = [];
  693. mmregs = [R_MM0..R_MM7];
  694. registers_saved_on_cdecl = [R_ESI,R_EDI,R_EBX];
  695. { generic register names }
  696. stack_pointer = R_ESP;
  697. frame_pointer = R_EBP;
  698. self_pointer = R_ESI;
  699. accumulator = R_EAX;
  700. { the register where the vmt offset is passed to the destructor }
  701. { helper routine }
  702. vmt_offset_reg = R_EDI;
  703. scratch_regs : array[1..1] of tregister = (R_EDI);
  704. max_scratch_regs = 1;
  705. {$ifndef noopt}
  706. { low and high of the available maximum width integer general purpose }
  707. { registers }
  708. LoGPReg = R_EAX;
  709. HiGPReg = R_EDI;
  710. { low and high of every possible width general purpose register (same as }
  711. { above on most architctures apart from the 80x86) }
  712. LoReg = R_EAX;
  713. HiReg = R_BL;
  714. {$endif noopt}
  715. cpuflags = [];
  716. { sizes }
  717. pointersize = 4;
  718. extended_size = 10;
  719. sizepostfix_pointer = S_L;
  720. {*****************************************************************************
  721. Instruction table
  722. *****************************************************************************}
  723. {$ifndef NOAG386BIN}
  724. type
  725. tinsentry=packed record
  726. opcode : tasmop;
  727. ops : byte;
  728. optypes : array[0..2] of longint;
  729. code : array[0..maxinfolen] of char;
  730. flags : longint;
  731. end;
  732. pinsentry=^tinsentry;
  733. TInsTabCache=array[TasmOp] of longint;
  734. PInsTabCache=^TInsTabCache;
  735. const
  736. InsTab:array[0..instabentries-1] of TInsEntry=
  737. {$i i386tab.inc}
  738. var
  739. InsTabCache : PInsTabCache;
  740. {$endif NOAG386BIN}
  741. {*****************************************************************************
  742. Init/Done
  743. *****************************************************************************}
  744. procedure InitCpu;
  745. procedure DoneCpu;
  746. {*****************************************************************************
  747. Helpers
  748. *****************************************************************************}
  749. const
  750. maxvarregs = 4;
  751. varregs : array[1..maxvarregs] of tregister =
  752. (R_EBX,R_EDX,R_ECX,R_EAX);
  753. maxfpuvarregs = 8;
  754. max_operands = 3;
  755. function imm_2_type(l:longint):longint;
  756. { the following functions allow to convert registers }
  757. { for example reg8toreg32(R_AL) returns R_EAX }
  758. { for example reg16toreg32(R_AL) gives an undefined }
  759. { result }
  760. { these functions expects that the turn of }
  761. { tregister isn't changed }
  762. function reg8toreg16(reg : tregister) : tregister;
  763. function reg8toreg32(reg : tregister) : tregister;
  764. function reg16toreg8(reg : tregister) : tregister;
  765. function reg32toreg8(reg : tregister) : tregister;
  766. function reg32toreg16(reg : tregister) : tregister;
  767. function reg16toreg32(reg : tregister) : tregister;
  768. { these procedures must be defined by all target cpus }
  769. function regtoreg8(reg : tregister) : tregister;
  770. function regtoreg16(reg : tregister) : tregister;
  771. function regtoreg32(reg : tregister) : tregister;
  772. { can be ignored on 32 bit systems }
  773. function regtoreg64(reg : tregister) : tregister;
  774. { returns the operand prefix for a given register }
  775. function regsize(reg : tregister) : topsize;
  776. { resets all values of ref to defaults }
  777. procedure reset_reference(var ref : treference);
  778. { set mostly used values of a new reference }
  779. function new_reference(base : tregister;offset : longint) : preference;
  780. function newreference(const r : treference) : preference;
  781. procedure disposereference(var r : preference);
  782. function reg2str(r : tregister) : string;
  783. function is_calljmp(o:tasmop):boolean;
  784. implementation
  785. {$ifdef heaptrc}
  786. uses
  787. ppheap;
  788. {$endif heaptrc}
  789. {*****************************************************************************
  790. Helpers
  791. *****************************************************************************}
  792. function imm_2_type(l:longint):longint;
  793. begin
  794. if (l>=-128) and (l<=127) then
  795. imm_2_type:=OT_IMM8 or OT_SIGNED
  796. else
  797. if (l>=-255) and (l<=255) then
  798. imm_2_type:=OT_IMM8
  799. else
  800. if (l>=-32768) and (l<=32767) then
  801. imm_2_type:=OT_IMM16 or OT_SIGNED
  802. else
  803. if (l>=-65536) and (l<=65535) then
  804. imm_2_type:=OT_IMM16 or OT_SIGNED
  805. else
  806. imm_2_type:=OT_IMM32;
  807. end;
  808. function reg2str(r : tregister) : string;
  809. const
  810. a : array[R_NO..R_BL] of string[3] =
  811. ('','EAX','ECX','EDX','EBX','ESP','EBP','ESI','EDI',
  812. 'AX','CX','DX','BX','SP','BP','SI','DI',
  813. 'AL','CL','DL','BL');
  814. begin
  815. if r in [R_ST0..R_ST7] then
  816. reg2str:='ST('+tostr(longint(r)-longint(R_ST0))+')'
  817. else
  818. reg2str:=a[r];
  819. end;
  820. function is_calljmp(o:tasmop):boolean;
  821. begin
  822. case o of
  823. A_CALL,
  824. A_JCXZ,
  825. A_JECXZ,
  826. A_JMP,
  827. A_LOOP,
  828. A_Jcc :
  829. is_calljmp:=true;
  830. else
  831. is_calljmp:=false;
  832. end;
  833. end;
  834. procedure disposereference(var r : preference);
  835. begin
  836. dispose(r);
  837. r:=nil;
  838. end;
  839. function newreference(const r : treference) : preference;
  840. var
  841. p : preference;
  842. begin
  843. new(p);
  844. p^:=r;
  845. newreference:=p;
  846. end;
  847. function reg8toreg16(reg : tregister) : tregister;
  848. begin
  849. reg8toreg16:=reg32toreg16(reg8toreg32(reg));
  850. end;
  851. function reg16toreg8(reg : tregister) : tregister;
  852. begin
  853. reg16toreg8:=reg32toreg8(reg16toreg32(reg));
  854. end;
  855. function reg16toreg32(reg : tregister) : tregister;
  856. begin
  857. reg16toreg32:=tregister(byte(reg)-byte(R_EDI));
  858. end;
  859. function reg32toreg16(reg : tregister) : tregister;
  860. begin
  861. reg32toreg16:=tregister(byte(reg)+byte(R_EDI));
  862. end;
  863. function reg32toreg8(reg : tregister) : tregister;
  864. begin
  865. reg32toreg8:=tregister(byte(reg)+byte(R_DI));
  866. end;
  867. function reg8toreg32(reg : tregister) : tregister;
  868. begin
  869. reg8toreg32:=tregister(byte(reg)-byte(R_DI));
  870. end;
  871. function regtoreg8(reg : tregister) : tregister;
  872. begin
  873. regtoreg8:=reg32toreg8(reg);
  874. end;
  875. function regtoreg16(reg : tregister) : tregister;
  876. begin
  877. regtoreg16:=reg32toreg16(reg);
  878. end;
  879. function regtoreg32(reg : tregister) : tregister;
  880. begin
  881. regtoreg32:=reg;
  882. end;
  883. function regtoreg64(reg : tregister) : tregister;
  884. begin
  885. { to avoid warning }
  886. regtoreg64:=R_NO;
  887. end;
  888. function regsize(reg : tregister) : topsize;
  889. begin
  890. if reg in regset8bit then
  891. regsize:=S_B
  892. else if reg in regset16bit then
  893. regsize:=S_W
  894. else if reg in regset32bit then
  895. regsize:=S_L;
  896. end;
  897. procedure reset_reference(var ref : treference);
  898. begin
  899. FillChar(ref,sizeof(treference),0);
  900. end;
  901. function new_reference(base : tregister;offset : longint) : preference;
  902. var
  903. r : preference;
  904. begin
  905. new(r);
  906. FillChar(r^,sizeof(treference),0);
  907. r^.base:=base;
  908. r^.offset:=offset;
  909. new_reference:=r;
  910. end;
  911. {*****************************************************************************
  912. Instruction table
  913. *****************************************************************************}
  914. procedure DoneCpu;
  915. begin
  916. {exitproc:=saveexit; }
  917. {$ifndef NOAG386BIN}
  918. if assigned(instabcache) then
  919. dispose(instabcache);
  920. {$endif NOAG386BIN}
  921. end;
  922. procedure BuildInsTabCache;
  923. {$ifndef NOAG386BIN}
  924. var
  925. i : longint;
  926. {$endif}
  927. begin
  928. {$ifndef NOAG386BIN}
  929. new(instabcache);
  930. FillChar(instabcache^,sizeof(tinstabcache),$ff);
  931. i:=0;
  932. while (i<InsTabEntries) do
  933. begin
  934. if InsTabCache^[InsTab[i].OPcode]=-1 then
  935. InsTabCache^[InsTab[i].OPcode]:=i;
  936. inc(i);
  937. end;
  938. {$endif NOAG386BIN}
  939. end;
  940. procedure InitCpu;
  941. begin
  942. {$ifndef NOAG386BIN}
  943. if not assigned(instabcache) then
  944. BuildInsTabCache;
  945. {$endif NOAG386BIN}
  946. end;
  947. end.
  948. {
  949. $Log$
  950. Revision 1.14 1999-10-14 14:57:51 florian
  951. - removed the hcodegen use in the new cg, use cgbase instead
  952. Revision 1.13 1999/09/15 20:35:39 florian
  953. * small fix to operator overloading when in MMX mode
  954. + the compiler uses now fldz and fld1 if possible
  955. + some fixes to floating point registers
  956. + some math. functions (arctan, ln, sin, cos, sqrt, sqr, pi) are now inlined
  957. * .... ???
  958. Revision 1.12 1999/09/10 18:48:01 florian
  959. * some bug fixes (e.g. must_be_valid and procinfo.funcret_is_valid)
  960. * most things for stored properties fixed
  961. Revision 1.11 1999/09/08 16:04:05 peter
  962. * better support for object fields and more error checks for
  963. field accesses which create buggy code
  964. Revision 1.10 1999/08/28 15:34:19 florian
  965. * bug 519 fixed
  966. Revision 1.9 1999/08/19 20:05:09 michael
  967. + Fixed ifdef NOAG386BIN bug
  968. Revision 1.8 1999/08/19 13:02:10 pierre
  969. + label faillabel added for _FAIL support
  970. Revision 1.7 1999/08/18 13:26:23 jonas
  971. + some constants for the new optimizer
  972. Revision 1.6 1999/08/13 15:36:30 peter
  973. * fixed suffix writing for a_setcc
  974. Revision 1.5 1999/08/12 14:36:02 peter
  975. + KNI instructions
  976. Revision 1.4 1999/08/07 14:20:58 florian
  977. * some small problems fixed
  978. Revision 1.3 1999/08/05 14:58:09 florian
  979. * some fixes for the floating point registers
  980. * more things for the new code generator
  981. Revision 1.2 1999/08/04 13:45:25 florian
  982. + floating point register variables !!
  983. * pairegalloc is now generated for register variables
  984. Revision 1.1 1999/08/04 00:22:58 florian
  985. * renamed i386asm and i386base to cpuasm and cpubase
  986. Revision 1.10 1999/08/02 21:28:58 florian
  987. * the main branch psub.pas is now used for
  988. newcg compiler
  989. Revision 1.9 1999/08/02 21:01:45 michael
  990. * Moved toperand type back =(
  991. Revision 1.8 1999/08/02 20:45:49 michael
  992. * Moved toperand type to aasm
  993. Revision 1.7 1999/08/02 17:17:09 florian
  994. * small changes for the new code generator
  995. Revision 1.6 1999/06/06 15:53:15 peter
  996. * suffix adding can be turned of for some tasmops in att_nosuffix array
  997. Revision 1.5 1999/05/27 19:44:34 peter
  998. * removed oldasm
  999. * plabel -> pasmlabel
  1000. * -a switches to source writing automaticly
  1001. * assembler readers OOPed
  1002. * asmsymbol automaticly external
  1003. * jumptables and other label fixes for asm readers
  1004. Revision 1.4 1999/05/17 14:33:50 pierre
  1005. uses heaptrc need for extrainfo with heaptrc
  1006. Revision 1.3 1999/05/12 00:19:51 peter
  1007. * removed R_DEFAULT_SEG
  1008. * uniform float names
  1009. Revision 1.2 1999/05/11 16:30:00 peter
  1010. * more noag386bin defines, so tp7 can compile at least
  1011. Revision 1.1 1999/05/01 13:24:23 peter
  1012. * merged nasm compiler
  1013. * old asm moved to oldasm/
  1014. Revision 1.13 1999/04/14 09:07:43 peter
  1015. * asm reader improvements
  1016. Revision 1.12 1999/04/10 16:14:09 peter
  1017. * fixed optimizer
  1018. Revision 1.11 1999/03/31 13:55:33 peter
  1019. * assembler inlining working for ag386bin
  1020. Revision 1.10 1999/03/29 16:05:50 peter
  1021. * optimizer working for ag386bin
  1022. Revision 1.9 1999/03/26 00:01:14 peter
  1023. * first things for optimizer (compiles but cycle crashes)
  1024. Revision 1.8 1999/03/06 17:24:21 peter
  1025. * rewritten intel parser a lot, especially reference reading
  1026. * size checking added for asm parsers
  1027. Revision 1.7 1999/03/02 02:56:20 peter
  1028. + stabs support for binary writers
  1029. * more fixes and missing updates from the previous commit :(
  1030. Revision 1.6 1999/03/01 15:46:22 peter
  1031. * ag386bin finally make cycles correct
  1032. * prefixes are now also normal opcodes
  1033. Revision 1.5 1999/02/26 00:48:29 peter
  1034. * assembler writers fixed for ag386bin
  1035. Revision 1.4 1999/02/25 21:03:04 peter
  1036. * ag386bin updates
  1037. + coff writer
  1038. Revision 1.3 1999/02/22 02:44:18 peter
  1039. * ag386bin doesn't use i386.pas anymore
  1040. Revision 1.2 1999/02/22 02:16:03 peter
  1041. * updates for ag386bin
  1042. Revision 1.1 1999/02/16 17:59:38 peter
  1043. + initial files
  1044. }