gencode.c 81 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156
  1. /* gencode.c -- Motorola 68HC11 & 68HC12 Emulator Generator
  2. Copyright 1999-2022 Free Software Foundation, Inc.
  3. Written by Stephane Carrez (stcarrez@nerim.fr)
  4. This file is part of GDB, GAS, and the GNU binutils.
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 3 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  15. /* This must come before any other includes. */
  16. #include "defs.h"
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <stdarg.h>
  21. #include <errno.h>
  22. #include "ansidecl.h"
  23. #include "libiberty.h"
  24. #include "opcode/m68hc11.h"
  25. /* Combination of CCR flags. */
  26. #define M6811_ZC_BIT M6811_Z_BIT|M6811_C_BIT
  27. #define M6811_NZ_BIT M6811_N_BIT|M6811_Z_BIT
  28. #define M6811_NZV_BIT M6811_N_BIT|M6811_Z_BIT|M6811_V_BIT
  29. #define M6811_NZC_BIT M6811_N_BIT|M6811_Z_BIT|M6811_C_BIT
  30. #define M6811_NVC_BIT M6811_N_BIT|M6811_V_BIT|M6811_C_BIT
  31. #define M6811_ZVC_BIT M6811_Z_BIT|M6811_V_BIT|M6811_C_BIT
  32. #define M6811_NZVC_BIT M6811_ZVC_BIT|M6811_N_BIT
  33. #define M6811_HNZVC_BIT M6811_NZVC_BIT|M6811_H_BIT
  34. #define M6811_HNVC_BIT M6811_NVC_BIT|M6811_H_BIT
  35. #define M6811_VC_BIT M6811_V_BIT|M6811_C_BIT
  36. /* Flags when the insn only changes some CCR flags. */
  37. #define CHG_NONE 0,0,0
  38. #define CHG_Z 0,0,M6811_Z_BIT
  39. #define CHG_C 0,0,M6811_C_BIT
  40. #define CHG_ZVC 0,0,M6811_ZVC_BIT
  41. #define CHG_NZC 0,0,M6811_NZC_BIT
  42. #define CHG_NZV 0,0,M6811_NZV_BIT
  43. #define CHG_NZVC 0,0,M6811_NZVC_BIT
  44. #define CHG_HNZVC 0,0,M6811_HNZVC_BIT
  45. #define CHG_ALL 0,0,0xff
  46. /* The insn clears and changes some flags. */
  47. #define CLR_I 0,M6811_I_BIT,0
  48. #define CLR_C 0,M6811_C_BIT,0
  49. #define CLR_V 0,M6811_V_BIT,0
  50. #define CLR_V_CHG_ZC 0,M6811_V_BIT,M6811_ZC_BIT
  51. #define CLR_V_CHG_NZ 0,M6811_V_BIT,M6811_NZ_BIT
  52. #define CLR_V_CHG_ZVC 0,M6811_V_BIT,M6811_ZVC_BIT
  53. #define CLR_N_CHG_ZVC 0,M6811_N_BIT,M6811_ZVC_BIT /* Used by lsr */
  54. #define CLR_VC_CHG_NZ 0,M6811_VC_BIT,M6811_NZ_BIT
  55. /* The insn sets some flags. */
  56. #define SET_I M6811_I_BIT,0,0
  57. #define SET_C M6811_C_BIT,0,0
  58. #define SET_V M6811_V_BIT,0,0
  59. #define SET_Z_CLR_NVC M6811_Z_BIT,M6811_NVC_BIT,0
  60. #define SET_C_CLR_V_CHG_NZ M6811_C_BIT,M6811_V_BIT,M6811_NZ_BIT
  61. #define SET_Z_CHG_HNVC M6811_Z_BIT,0,M6811_HNVC_BIT
  62. #define _M 0xff
  63. static int cpu_type;
  64. struct m6811_opcode_pattern
  65. {
  66. const char *name;
  67. const char *pattern;
  68. const char *ccr_update;
  69. };
  70. /*
  71. * { "test", M6811_OP_NONE, 1, 0x00, 5, _M, CHG_NONE },
  72. * Name -+ +---- Insn CCR changes
  73. * Format ------+ +---------- Max # cycles
  74. * Size -----------------+ +--------------- Min # cycles
  75. * +-------------------- Opcode
  76. */
  77. struct m6811_opcode_pattern m6811_opcode_patterns[] = {
  78. /* Move 8 and 16 bits. We need two implementations: one that sets the
  79. flags and one that preserve them. */
  80. { "movtst8", "dst8 = src8", "cpu_ccr_update_tst8 (cpu, dst8)" },
  81. { "movtst16", "dst16 = src16", "cpu_ccr_update_tst16 (cpu, dst16)" },
  82. { "mov8", "dst8 = src8" },
  83. { "mov16", "dst16 = src16" },
  84. { "lea16", "dst16 = addr" },
  85. /* Conditional branches. 'addr' is the address of the branch. */
  86. { "bra", "cpu_set_pc (cpu, addr)" },
  87. { "bhi",
  88. "if ((cpu_get_ccr (cpu) & (M6811_C_BIT|M6811_Z_BIT)) == 0)\n@ \
  89. cpu_set_pc (cpu, addr)" },
  90. { "bls",
  91. "if ((cpu_get_ccr (cpu) & (M6811_C_BIT|M6811_Z_BIT)))\n@ \
  92. cpu_set_pc (cpu, addr)" },
  93. { "bcc", "if (!cpu_get_ccr_C (cpu))\n@ cpu_set_pc (cpu, addr)" },
  94. { "bcs", "if (cpu_get_ccr_C (cpu))\n@ cpu_set_pc (cpu, addr)" },
  95. { "bne", "if (!cpu_get_ccr_Z (cpu))\n@ cpu_set_pc (cpu, addr)" },
  96. { "beq", "if (cpu_get_ccr_Z (cpu))\n@ cpu_set_pc (cpu, addr)" },
  97. { "bvc", "if (!cpu_get_ccr_V (cpu))\n@ cpu_set_pc (cpu, addr)" },
  98. { "bvs", "if (cpu_get_ccr_V (cpu))\n@ cpu_set_pc (cpu, addr)" },
  99. { "bpl", "if (!cpu_get_ccr_N (cpu))\n@ cpu_set_pc (cpu, addr)" },
  100. { "bmi", "if (cpu_get_ccr_N (cpu))\n@ cpu_set_pc (cpu, addr)" },
  101. { "bge", "if ((cpu_get_ccr_N (cpu) ^ cpu_get_ccr_V (cpu)) == 0)\n@ cpu_set_pc (cpu, addr)" },
  102. { "blt", "if ((cpu_get_ccr_N (cpu) ^ cpu_get_ccr_V (cpu)))\n@ cpu_set_pc (cpu, addr)" },
  103. { "bgt",
  104. "if ((cpu_get_ccr_Z (cpu) | (cpu_get_ccr_N (cpu) ^ cpu_get_ccr_V (cpu))) == 0)\n@ \
  105. cpu_set_pc (cpu, addr)" },
  106. { "ble",
  107. "if ((cpu_get_ccr_Z (cpu) | (cpu_get_ccr_N (cpu) ^ cpu_get_ccr_V (cpu))))\n@ \
  108. cpu_set_pc (cpu, addr)" },
  109. /* brclr and brset perform a test and a conditional jump at the same
  110. time. Flags are not changed. */
  111. { "brclr8",
  112. "if ((src8 & dst8) == 0)\n@ cpu_set_pc (cpu, addr)" },
  113. { "brset8",
  114. "if (((~src8) & dst8) == 0)\n@ cpu_set_pc (cpu, addr)" },
  115. { "rts11", "addr = cpu_m68hc11_pop_uint16 (cpu); cpu_set_pc (cpu, addr); cpu_return (cpu)" },
  116. { "rts12", "addr = cpu_m68hc12_pop_uint16 (cpu); cpu_set_pc (cpu, addr); cpu_return (cpu)" },
  117. { "mul16", "dst16 = ((uint16_t) src8 & 0x0FF) * ((uint16_t) dst8 & 0x0FF)",
  118. "cpu_set_ccr_C (cpu, src8 & 0x80)" },
  119. { "neg8", "dst8 = - src8",
  120. "cpu_set_ccr_C (cpu, src8 == 0); cpu_ccr_update_tst8 (cpu, dst8)" },
  121. { "com8", "dst8 = ~src8",
  122. "cpu_set_ccr_C (cpu, 1); cpu_ccr_update_tst8 (cpu, dst8);" },
  123. { "clr8", "dst8 = 0",
  124. "cpu_set_ccr (cpu, (cpu_get_ccr (cpu) & (M6811_S_BIT|M6811_X_BIT|M6811_H_BIT| \
  125. M6811_I_BIT)) | M6811_Z_BIT)"},
  126. { "clr16","dst16 = 0",
  127. "cpu_set_ccr (cpu, (cpu_get_ccr (cpu) & (M6811_S_BIT|M6811_X_BIT|M6811_H_BIT| \
  128. M6811_I_BIR)) | M6811_Z_BIT)"},
  129. /* 8-bits shift and rotation. */
  130. { "lsr8", "dst8 = src8 >> 1",
  131. "cpu_set_ccr_C (cpu, src8 & 1); cpu_ccr_update_shift8 (cpu, dst8)" },
  132. { "lsl8", "dst8 = src8 << 1",
  133. "cpu_set_ccr_C (cpu, (src8 & 0x80) >> 7); cpu_ccr_update_shift8 (cpu, dst8)" },
  134. { "asr8", "dst8 = (src8 >> 1) | (src8 & 0x80)",
  135. "cpu_set_ccr_C (cpu, src8 & 1); cpu_ccr_update_shift8 (cpu, dst8)" },
  136. { "ror8", "dst8 = (src8 >> 1) | (cpu_get_ccr_C (cpu) << 7)",
  137. "cpu_set_ccr_C (cpu, src8 & 1); cpu_ccr_update_shift8 (cpu, dst8)" },
  138. { "rol8", "dst8 = (src8 << 1) | (cpu_get_ccr_C (cpu))",
  139. "cpu_set_ccr_C (cpu, (src8 & 0x80) >> 7); cpu_ccr_update_shift8 (cpu, dst8)" },
  140. /* 16-bits shift instructions. */
  141. { "lsl16", "dst16 = src16 << 1",
  142. "cpu_set_ccr_C (cpu, (src16&0x8000) >> 15); cpu_ccr_update_shift16 (cpu, dst16)"},
  143. { "lsr16", "dst16 = src16 >> 1",
  144. "cpu_set_ccr_C (cpu, src16 & 1); cpu_ccr_update_shift16 (cpu, dst16)"},
  145. { "dec8", "dst8 = src8 - 1", "cpu_ccr_update_tst8 (cpu, dst8)" },
  146. { "inc8", "dst8 = src8 + 1", "cpu_ccr_update_tst8 (cpu, dst8)" },
  147. { "tst8", 0, "cpu_set_ccr_C (cpu, 0); cpu_ccr_update_tst8 (cpu, src8)" },
  148. { "sub8", "cpu_ccr_update_sub8 (cpu, dst8 - src8, dst8, src8);\
  149. dst8 = dst8 - src8", 0 },
  150. { "add8", "cpu_ccr_update_add8 (cpu, dst8 + src8, dst8, src8);\
  151. dst8 = dst8 + src8", 0 },
  152. { "sbc8", "if (cpu_get_ccr_C (cpu))\n@ \
  153. {\n\
  154. cpu_ccr_update_sub8 (cpu, dst8 - src8 - 1, dst8, src8);\n\
  155. dst8 = dst8 - src8 - 1;\n\
  156. }\n\
  157. else\n\
  158. {\n\
  159. cpu_ccr_update_sub8 (cpu, dst8 - src8, dst8, src8);\n\
  160. dst8 = dst8 - src8;\n\
  161. }", 0 },
  162. { "adc8", "if (cpu_get_ccr_C (cpu))\n@ \
  163. {\n\
  164. cpu_ccr_update_add8 (cpu, dst8 + src8 + 1, dst8, src8);\n\
  165. dst8 = dst8 + src8 + 1;\n\
  166. }\n\
  167. else\n\
  168. {\n\
  169. cpu_ccr_update_add8 (cpu, dst8 + src8, dst8, src8);\n\
  170. dst8 = dst8 + src8;\n\
  171. }",
  172. 0 },
  173. /* 8-bits logical operations. */
  174. { "and8", "dst8 = dst8 & src8", "cpu_ccr_update_tst8 (cpu, dst8)" },
  175. { "eor8", "dst8 = dst8 ^ src8", "cpu_ccr_update_tst8 (cpu, dst8)" },
  176. { "or8", "dst8 = dst8 | src8", "cpu_ccr_update_tst8 (cpu, dst8)" },
  177. { "bclr8","dst8 = (~dst8) & src8", "cpu_ccr_update_tst8 (cpu, dst8)" },
  178. /* 16-bits add and subtract instructions. */
  179. { "sub16", "cpu_ccr_update_sub16 (cpu, dst16 - src16, dst16, src16);\
  180. dst16 = dst16 - src16", 0 },
  181. { "add16", "cpu_ccr_update_add16 (cpu, dst16 + src16, dst16, src16);\
  182. dst16 = dst16 + src16", 0 },
  183. { "inc16", "dst16 = src16 + 1", "cpu_set_ccr_Z (cpu, dst16 == 0)" },
  184. { "dec16", "dst16 = src16 - 1", "cpu_set_ccr_Z (cpu, dst16 == 0)" },
  185. /* Special increment/decrement for the stack pointer:
  186. flags are not changed. */
  187. { "ins16", "dst16 = src16 + 1" },
  188. { "des16", "dst16 = src16 - 1" },
  189. { "jsr_11_16", "cpu_m68hc11_push_uint16 (cpu, cpu_get_pc (cpu)); cpu_call (cpu, addr)"},
  190. { "jsr_12_16", "cpu_m68hc12_push_uint16 (cpu, cpu_get_pc (cpu)); cpu_call (cpu, addr)"},
  191. /* xgdx and xgdx patterns. Flags are not changed. */
  192. { "xgdxy16", "dst16 = cpu_get_d (cpu); cpu_set_d (cpu, src16)"},
  193. { "stop", "cpu_special (cpu, M6811_STOP)"},
  194. /* tsx, tsy, txs, tys don't affect the flags. Sp value is corrected
  195. by +/- 1. */
  196. { "tsxy16", "dst16 = src16 + 1;"},
  197. { "txys16", "dst16 = src16 - 1;"},
  198. /* Add b to X or Y with an unsigned extension 8->16. Flags not changed. */
  199. { "abxy16","dst16 = dst16 + (uint16_t) src8"},
  200. /* After 'daa', the Z flag is undefined. Mark it as changed. */
  201. { "daa8", "cpu_special (cpu, M6811_DAA)" },
  202. { "nop", 0 },
  203. /* Integer divide:
  204. (parallel (set IX (div D IX))
  205. (set D (mod D IX))) */
  206. { "idiv16", "if (src16 == 0)\n{\n\
  207. dst16 = 0xffff;\
  208. }\nelse\n{\n\
  209. cpu_set_d (cpu, dst16 % src16);\
  210. dst16 = dst16 / src16;\
  211. }",
  212. "cpu_set_ccr_Z (cpu, dst16 == 0); cpu_set_ccr_V (cpu, 0);\
  213. cpu_set_ccr_C (cpu, src16 == 0)" },
  214. /* Fractional divide:
  215. (parallel (set IX (div (mul D 65536) IX)
  216. (set D (mod (mul D 65536) IX)))) */
  217. { "fdiv16", "if (src16 <= dst16 )\n{\n\
  218. dst16 = 0xffff;\n\
  219. cpu_set_ccr_Z (cpu, 0);\n\
  220. cpu_set_ccr_V (cpu, 1);\n\
  221. cpu_set_ccr_C (cpu, dst16 == 0);\n\
  222. }\nelse\n{\n\
  223. unsigned long l = (unsigned long) (dst16) << 16;\n\
  224. cpu_set_d (cpu, (uint16_t) (l % (unsigned long) (src16)));\n\
  225. dst16 = (uint16_t) (l / (unsigned long) (src16));\n\
  226. cpu_set_ccr_V (cpu, 0);\n\
  227. cpu_set_ccr_C (cpu, 0);\n\
  228. cpu_set_ccr_Z (cpu, dst16 == 0);\n\
  229. }", 0 },
  230. /* Operations to get/set the CCR. */
  231. { "clv", 0, "cpu_set_ccr_V (cpu, 0)" },
  232. { "sev", 0, "cpu_set_ccr_V (cpu, 1)" },
  233. { "clc", 0, "cpu_set_ccr_C (cpu, 0)" },
  234. { "sec", 0, "cpu_set_ccr_C (cpu, 1)" },
  235. { "cli", 0, "cpu_set_ccr_I (cpu, 0)" },
  236. { "sei", 0, "cpu_set_ccr_I (cpu, 1)" },
  237. /* Some special instructions are implemented by 'cpu_special'. */
  238. { "rti11", "cpu_special (cpu, M6811_RTI)" },
  239. { "rti12", "cpu_special (cpu, M6812_RTI)" },
  240. { "wai", "cpu_special (cpu, M6811_WAI)" },
  241. { "test", "cpu_special (cpu, M6811_TEST)" },
  242. { "swi", "cpu_special (cpu, M6811_SWI)" },
  243. { "syscall","cpu_special (cpu, M6811_EMUL_SYSCALL)" },
  244. { "page2", "cpu_page2_interp (cpu)", 0 },
  245. { "page3", "cpu_page3_interp (cpu)", 0 },
  246. { "page4", "cpu_page4_interp (cpu)", 0 },
  247. /* 68HC12 special instructions. */
  248. { "bgnd", "cpu_special (cpu, M6812_BGND)" },
  249. { "call8", "cpu_special (cpu, M6812_CALL)" },
  250. { "call_ind", "cpu_special (cpu, M6812_CALL_INDIRECT)" },
  251. { "dbcc8", "cpu_dbcc (cpu)" },
  252. { "ediv", "cpu_special (cpu, M6812_EDIV)" },
  253. { "emul", "{ uint32_t src1 = (uint32_t) cpu_get_d (cpu);\
  254. uint32_t src2 = (uint32_t) cpu_get_y (cpu);\
  255. src1 *= src2;\
  256. cpu_set_d (cpu, src1);\
  257. cpu_set_y (cpu, src1 >> 16);\
  258. cpu_set_ccr_Z (cpu, src1 == 0);\
  259. cpu_set_ccr_C (cpu, src1 & 0x08000);\
  260. cpu_set_ccr_N (cpu, src1 & 0x80000000);}" },
  261. { "emuls", "cpu_special (cpu, M6812_EMULS)" },
  262. { "mem", "cpu_special (cpu, M6812_MEM)" },
  263. { "rtc", "cpu_special (cpu, M6812_RTC)" },
  264. { "emacs", "cpu_special (cpu, M6812_EMACS)" },
  265. { "idivs", "cpu_special (cpu, M6812_IDIVS)" },
  266. { "edivs", "cpu_special (cpu, M6812_EDIVS)" },
  267. { "exg8", "cpu_exg (cpu, src8)" },
  268. { "move8", "cpu_move8 (cpu, op)" },
  269. { "move16","cpu_move16 (cpu, op)" },
  270. { "max8", "cpu_ccr_update_sub8 (cpu, dst8 - src8, dst8, src8);\
  271. if (dst8 < src8) dst8 = src8" },
  272. { "min8", "cpu_ccr_update_sub8 (cpu, dst8 - src8, dst8, src8);\
  273. if (dst8 > src8) dst8 = src8" },
  274. { "max16", "cpu_ccr_update_sub16 (cpu, dst16 - src16, dst16, src16);\
  275. if (dst16 < src16) dst16 = src16" },
  276. { "min16", "cpu_ccr_update_sub16 (cpu, dst16 - src16, dst16, src16);\
  277. if (dst16 > src16) dst16 = src16" },
  278. { "rev", "cpu_special (cpu, M6812_REV);" },
  279. { "revw", "cpu_special (cpu, M6812_REVW);" },
  280. { "wav", "cpu_special (cpu, M6812_WAV);" },
  281. { "tbl8", "cpu_special (cpu, M6812_ETBL);" },
  282. { "tbl16", "cpu_special (cpu, M6812_ETBL);" }
  283. };
  284. /* Definition of an opcode of the 68HC11. */
  285. struct m6811_opcode_def
  286. {
  287. const char *name;
  288. const char *operands;
  289. const char *insn_pattern;
  290. unsigned char insn_size;
  291. unsigned char insn_code;
  292. unsigned char insn_min_cycles;
  293. unsigned char insn_max_cycles;
  294. unsigned char set_flags_mask;
  295. unsigned char clr_flags_mask;
  296. unsigned char chg_flags_mask;
  297. };
  298. /*
  299. * { "dex", "x->x", "dec16", 1, 0x00, 5, _M, CHG_NONE },
  300. * Name -+ +----- Insn CCR changes
  301. * Operands ---+ +------------ Max # cycles
  302. * Pattern -----------+ +--------------- Min # cycles
  303. * Size -----------------+ +-------------------- Opcode
  304. *
  305. * Operands Fetch operand Save result
  306. * ------- -------------- ------------
  307. * x->x src16 = x x = dst16
  308. * d->d src16 = d d = dst16
  309. * b,a->a src8 = b dst8 = a a = dst8
  310. * sp->x src16 = sp x = dst16
  311. * (sp)->a src8 = pop8 a = dst8
  312. * a->(sp) src8 = a push8 dst8
  313. * (x)->(x) src8 = (IND, X) (IND, X) = dst8
  314. * (y)->a src8 = (IND, Y) a = dst8
  315. * ()->b src8 = (EXT) b = dst8
  316. */
  317. struct m6811_opcode_def m6811_page1_opcodes[] = {
  318. { "test", 0, 0, 1, 0x00, 5, _M, CHG_NONE },
  319. { "nop", 0, 0, 1, 0x01, 2, 2, CHG_NONE },
  320. { "idiv", "x,d->x", "idiv16", 1, 0x02, 3, 41, CLR_V_CHG_ZC},
  321. { "fdiv", "x,d->x", "fdiv16", 1, 0x03, 3, 41, CHG_ZVC},
  322. { "lsrd", "d->d", "lsr16", 1, 0x04, 3, 3, CLR_N_CHG_ZVC },
  323. { "asld", "d->d", "lsl16", 1, 0x05, 3, 3, CHG_NZVC },
  324. { "tap", "a->ccr", "mov8", 1, 0x06, 2, 2, CHG_ALL},
  325. { "tpa", "ccr->a", "mov8", 1, 0x07, 2, 2, CHG_NONE },
  326. { "inx", "x->x", "inc16", 1, 0x08, 3, 3, CHG_Z },
  327. { "dex", "x->x", "dec16", 1, 0x09, 3, 3, CHG_Z },
  328. { "clv", 0, 0, 1, 0x0a, 2, 2, CLR_V },
  329. { "sev", 0, 0, 1, 0x0b, 2, 2, SET_V },
  330. { "clc", 0, 0, 1, 0x0c, 2, 2, CLR_C },
  331. { "sec", 0, 0, 1, 0x0d, 2, 2, SET_C },
  332. { "cli", 0, 0, 1, 0x0e, 2, 2, CLR_I },
  333. { "sei", 0, 0, 1, 0x0f, 2, 2, SET_I },
  334. { "sba", "b,a->a", "sub8", 1, 0x10, 2, 2, CHG_NZVC },
  335. { "cba", "b,a", "sub8", 1, 0x11, 2, 2, CHG_NZVC },
  336. { "brset","*,#,r", "brset8", 4, 0x12, 6, 6, CHG_NONE },
  337. { "brclr","*,#,r", "brclr8", 4, 0x13, 6, 6, CHG_NONE },
  338. { "bset", "*,#->*", "or8", 3, 0x14, 6, 6, CLR_V_CHG_NZ },
  339. { "bclr", "*,#->*", "bclr8", 3, 0x15, 6, 6, CLR_V_CHG_NZ },
  340. { "tab", "a->b", "movtst8", 1, 0x16, 2, 2, CLR_V_CHG_NZ },
  341. { "tba", "b->a", "movtst8", 1, 0x17, 2, 2, CLR_V_CHG_NZ },
  342. { "page2", 0, "page2", 1, 0x18, 0, 0, CHG_NONE },
  343. { "page3", 0, "page3", 1, 0x1a, 0, 0, CHG_NONE },
  344. /* After 'daa', the Z flag is undefined. Mark it as changed. */
  345. { "daa", "", "daa8", 1, 0x19, 2, 2, CHG_NZVC },
  346. { "aba", "b,a->a", "add8", 1, 0x1b, 2, 2, CHG_HNZVC},
  347. { "bset", "(x),#->(x)","or8", 3, 0x1c, 7, 7, CLR_V_CHG_NZ },
  348. { "bclr", "(x),#->(x)","bclr8", 3, 0x1d, 7, 7, CLR_V_CHG_NZ },
  349. { "brset","(x),#,r", "brset8", 4, 0x1e, 7, 7, CHG_NONE },
  350. { "brclr","(x),#,r", "brclr8", 4, 0x1f, 7, 7, CHG_NONE },
  351. /* Relative branch. All of them take 3 bytes. Flags not changed. */
  352. { "bra", "r", 0, 2, 0x20, 3, 3, CHG_NONE },
  353. { "brn", "r", "nop", 2, 0x21, 3, 3, CHG_NONE },
  354. { "bhi", "r", 0, 2, 0x22, 3, 3, CHG_NONE },
  355. { "bls", "r", 0, 2, 0x23, 3, 3, CHG_NONE },
  356. { "bcc", "r", 0, 2, 0x24, 3, 3, CHG_NONE },
  357. { "bcs", "r", 0, 2, 0x25, 3, 3, CHG_NONE },
  358. { "bne", "r", 0, 2, 0x26, 3, 3, CHG_NONE },
  359. { "beq", "r", 0, 2, 0x27, 3, 3, CHG_NONE },
  360. { "bvc", "r", 0, 2, 0x28, 3, 3, CHG_NONE },
  361. { "bvs", "r", 0, 2, 0x29, 3, 3, CHG_NONE },
  362. { "bpl", "r", 0, 2, 0x2a, 3, 3, CHG_NONE },
  363. { "bmi", "r", 0, 2, 0x2b, 3, 3, CHG_NONE },
  364. { "bge", "r", 0, 2, 0x2c, 3, 3, CHG_NONE },
  365. { "blt", "r", 0, 2, 0x2d, 3, 3, CHG_NONE },
  366. { "bgt", "r", 0, 2, 0x2e, 3, 3, CHG_NONE },
  367. { "ble", "r", 0, 2, 0x2f, 3, 3, CHG_NONE },
  368. { "tsx", "sp->x", "tsxy16", 1, 0x30, 3, 3, CHG_NONE },
  369. { "ins", "sp->sp", "ins16", 1, 0x31, 3, 3, CHG_NONE },
  370. { "pula", "(sp)->a", "mov8", 1, 0x32, 4, 4, CHG_NONE },
  371. { "pulb", "(sp)->b", "mov8", 1, 0x33, 4, 4, CHG_NONE },
  372. { "des", "sp->sp", "des16", 1, 0x34, 3, 3, CHG_NONE },
  373. { "txs", "x->sp", "txys16", 1, 0x35, 3, 3, CHG_NONE },
  374. { "psha", "a->(sp)", "mov8", 1, 0x36, 3, 3, CHG_NONE },
  375. { "pshb", "b->(sp)", "mov8", 1, 0x37, 3, 3, CHG_NONE },
  376. { "pulx", "(sp)->x", "mov16", 1, 0x38, 5, 5, CHG_NONE },
  377. { "rts", 0, "rts11", 1, 0x39, 5, 5, CHG_NONE },
  378. { "abx", "b,x->x", "abxy16", 1, 0x3a, 3, 3, CHG_NONE },
  379. { "rti", 0, "rti11", 1, 0x3b, 12, 12, CHG_ALL},
  380. { "pshx", "x->(sp)", "mov16", 1, 0x3c, 4, 4, CHG_NONE },
  381. { "mul", "b,a->d", "mul16", 1, 0x3d, 3, 10, CHG_C },
  382. { "wai", 0, 0, 1, 0x3e, 14, _M, CHG_NONE },
  383. { "swi", 0, 0, 1, 0x3f, 14, _M, CHG_NONE },
  384. { "nega", "a->a", "neg8", 1, 0x40, 2, 2, CHG_NZVC },
  385. { "syscall", "", "syscall", 1, 0x41, 2, 2, CHG_NONE },
  386. { "coma", "a->a", "com8", 1, 0x43, 2, 2, SET_C_CLR_V_CHG_NZ },
  387. { "lsra", "a->a", "lsr8", 1, 0x44, 2, 2, CLR_N_CHG_ZVC},
  388. { "rora", "a->a", "ror8", 1, 0x46, 2, 2, CHG_NZVC },
  389. { "asra", "a->a", "asr8", 1, 0x47, 2, 2, CHG_NZVC },
  390. { "asla", "a->a", "lsl8", 1, 0x48, 2, 2, CHG_NZVC },
  391. { "rola", "a->a", "rol8", 1, 0x49, 2, 2, CHG_NZVC },
  392. { "deca", "a->a", "dec8", 1, 0x4a, 2, 2, CHG_NZV },
  393. { "inca", "a->a", "inc8", 1, 0x4c, 2, 2, CHG_NZV },
  394. { "tsta", "a", "tst8", 1, 0x4d, 2, 2, CLR_V_CHG_NZ },
  395. { "clra", "->a", "clr8", 1, 0x4f, 2, 2, SET_Z_CLR_NVC },
  396. { "negb", "b->b", "neg8", 1, 0x50, 2, 2, CHG_NZVC },
  397. { "comb", "b->b", "com8", 1, 0x53, 2, 2, SET_C_CLR_V_CHG_NZ },
  398. { "lsrb", "b->b", "lsr8", 1, 0x54, 2, 2, CLR_N_CHG_ZVC },
  399. { "rorb", "b->b", "ror8", 1, 0x56, 2, 2, CHG_NZVC },
  400. { "asrb", "b->b", "asr8", 1, 0x57, 2, 2, CHG_NZVC },
  401. { "aslb", "b->b", "lsl8", 1, 0x58, 2, 2, CHG_NZVC },
  402. { "rolb", "b->b", "rol8", 1, 0x59, 2, 2, CHG_NZVC },
  403. { "decb", "b->b", "dec8", 1, 0x5a, 2, 2, CHG_NZV },
  404. { "incb", "b->b", "inc8", 1, 0x5c, 2, 2, CHG_NZV },
  405. { "tstb", "b", "tst8", 1, 0x5d, 2, 2, CLR_V_CHG_NZ },
  406. { "clrb", "->b", "clr8", 1, 0x5f, 2, 2, SET_Z_CLR_NVC },
  407. { "neg", "(x)->(x)", "neg8", 2, 0x60, 6, 6, CHG_NZVC },
  408. { "com", "(x)->(x)", "com8", 2, 0x63, 6, 6, SET_C_CLR_V_CHG_NZ },
  409. { "lsr", "(x)->(x)", "lsr8", 2, 0x64, 6, 6, CLR_N_CHG_ZVC },
  410. { "ror", "(x)->(x)", "ror8", 2, 0x66, 6, 6, CHG_NZVC },
  411. { "asr", "(x)->(x)", "asr8", 2, 0x67, 6, 6, CHG_NZVC },
  412. { "asl", "(x)->(x)", "lsl8", 2, 0x68, 6, 6, CHG_NZVC },
  413. { "rol", "(x)->(x)", "rol8", 2, 0x69, 6, 6, CHG_NZVC },
  414. { "dec", "(x)->(x)", "dec8", 2, 0x6a, 6, 6, CHG_NZV },
  415. { "inc", "(x)->(x)", "inc8", 2, 0x6c, 6, 6, CHG_NZV },
  416. { "tst", "(x)", "tst8", 2, 0x6d, 6, 6, CLR_V_CHG_NZ },
  417. { "jmp", "&(x)", "bra", 2, 0x6e, 3, 3, CHG_NONE },
  418. { "clr", "->(x)", "clr8", 2, 0x6f, 6, 6, SET_Z_CLR_NVC },
  419. { "neg", "()->()", "neg8", 3, 0x70, 6, 6, CHG_NZVC },
  420. { "com", "()->()", "com8", 3, 0x73, 6, 6, SET_C_CLR_V_CHG_NZ },
  421. { "lsr", "()->()", "lsr8", 3, 0x74, 6, 6, CLR_V_CHG_ZVC },
  422. { "ror", "()->()", "ror8", 3, 0x76, 6, 6, CHG_NZVC },
  423. { "asr", "()->()", "asr8", 3, 0x77, 6, 6, CHG_NZVC },
  424. { "asl", "()->()", "lsl8", 3, 0x78, 6, 6, CHG_NZVC },
  425. { "rol", "()->()", "rol8", 3, 0x79, 6, 6, CHG_NZVC },
  426. { "dec", "()->()", "dec8", 3, 0x7a, 6, 6, CHG_NZV },
  427. { "inc", "()->()", "inc8", 3, 0x7c, 6, 6, CHG_NZV },
  428. { "tst", "()", "tst8", 3, 0x7d, 6, 6, CLR_V_CHG_NZ },
  429. { "jmp", "&()", "bra", 3, 0x7e, 3, 3, CHG_NONE },
  430. { "clr", "->()", "clr8", 3, 0x7f, 6, 6, SET_Z_CLR_NVC },
  431. { "suba", "#,a->a", "sub8", 2, 0x80, 2, 2, CHG_NZVC },
  432. { "cmpa", "#,a", "sub8", 2, 0x81, 2, 2, CHG_NZVC },
  433. { "sbca", "#,a->a", "sbc8", 2, 0x82, 2, 2, CHG_NZVC },
  434. { "subd", "#,d->d", "sub16", 3, 0x83, 4, 4, CHG_NZVC },
  435. { "anda", "#,a->a", "and8", 2, 0x84, 2, 2, CLR_V_CHG_NZ },
  436. { "bita", "#,a", "and8", 2, 0x85, 2, 2, CLR_V_CHG_NZ },
  437. { "ldaa", "#->a", "movtst8", 2, 0x86, 2, 2, CLR_V_CHG_NZ },
  438. { "eora", "#,a->a", "eor8", 2, 0x88, 2, 2, CLR_V_CHG_NZ },
  439. { "adca", "#,a->a", "adc8", 2, 0x89, 2, 2, CHG_HNZVC },
  440. { "oraa", "#,a->a", "or8", 2, 0x8a, 2, 2, CLR_V_CHG_NZ },
  441. { "adda", "#,a->a", "add8", 2, 0x8b, 2, 2, CHG_HNZVC },
  442. { "cmpx", "#,x", "sub16", 3, 0x8c, 4, 4, CHG_NZVC },
  443. { "bsr", "r", "jsr_11_16", 2, 0x8d, 6, 6, CHG_NONE },
  444. { "lds", "#->sp", "movtst16", 3, 0x8e, 3, 3, CLR_V_CHG_NZ },
  445. { "xgdx", "x->x", "xgdxy16", 1, 0x8f, 3, 3, CHG_NONE },
  446. { "suba", "*,a->a", "sub8", 2, 0x90, 3, 3, CHG_NZVC },
  447. { "cmpa", "*,a", "sub8", 2, 0x91, 3, 3, CHG_NZVC },
  448. { "sbca", "*,a->a", "sbc8", 2, 0x92, 3, 3, CHG_NZVC },
  449. { "subd", "*,d->d", "sub16", 2, 0x93, 5, 5, CHG_NZVC },
  450. { "anda", "*,a->a", "and8", 2, 0x94, 3, 3, CLR_V_CHG_NZ },
  451. { "bita", "*,a", "and8", 2, 0x95, 3, 3, CLR_V_CHG_NZ },
  452. { "ldaa", "*->a", "movtst8", 2, 0x96, 3, 3, CLR_V_CHG_NZ },
  453. { "staa", "a->*", "movtst8", 2, 0x97, 3, 3, CLR_V_CHG_NZ },
  454. { "eora", "*,a->a", "eor8", 2, 0x98, 3, 3, CLR_V_CHG_NZ },
  455. { "adca", "*,a->a", "adc8", 2, 0x99, 3, 3, CHG_HNZVC },
  456. { "oraa", "*,a->a", "or8", 2, 0x9a, 3, 3, CLR_V_CHG_NZ },
  457. { "adda", "*,a->a", "add8", 2, 0x9b, 3, 3, CHG_HNZVC },
  458. { "cmpx", "*,x", "sub16", 2, 0x9c, 5, 5, CHG_NZVC },
  459. { "jsr", "*", "jsr_11_16", 2, 0x9d, 5, 5, CHG_NONE },
  460. { "lds", "*->sp", "movtst16", 2, 0x9e, 4, 4, CLR_V_CHG_NZ },
  461. { "sts", "sp->*", "movtst16", 2, 0x9f, 4, 4, CLR_V_CHG_NZ },
  462. { "suba", "(x),a->a", "sub8", 2, 0xa0, 4, 4, CHG_NZVC },
  463. { "cmpa", "(x),a", "sub8", 2, 0xa1, 4, 4, CHG_NZVC },
  464. { "sbca", "(x),a->a", "sbc8", 2, 0xa2, 4, 4, CHG_NZVC },
  465. { "subd", "(x),d->d", "sub16", 2, 0xa3, 6, 6, CHG_NZVC },
  466. { "anda", "(x),a->a", "and8", 2, 0xa4, 4, 4, CLR_V_CHG_NZ },
  467. { "bita", "(x),a", "and8", 2, 0xa5, 4, 4, CLR_V_CHG_NZ },
  468. { "ldaa", "(x)->a", "movtst8", 2, 0xa6, 4, 4, CLR_V_CHG_NZ },
  469. { "staa", "a->(x)", "movtst8", 2, 0xa7, 4, 4, CLR_V_CHG_NZ },
  470. { "eora", "(x),a->a", "eor8", 2, 0xa8, 4, 4, CLR_V_CHG_NZ },
  471. { "adca", "(x),a->a", "adc8", 2, 0xa9, 4, 4, CHG_HNZVC },
  472. { "oraa", "(x),a->a", "or8", 2, 0xaa, 4, 4, CLR_V_CHG_NZ },
  473. { "adda", "(x),a->a", "add8", 2, 0xab, 4, 4, CHG_HNZVC },
  474. { "cmpx", "(x),x", "sub16", 2, 0xac, 6, 6, CHG_NZVC },
  475. { "jsr", "&(x)", "jsr_11_16", 2, 0xad, 6, 6, CHG_NONE },
  476. { "lds", "(x)->sp", "movtst16", 2, 0xae, 5, 5, CLR_V_CHG_NZ },
  477. { "sts", "sp->(x)", "movtst16", 2, 0xaf, 5, 5, CLR_V_CHG_NZ },
  478. { "suba", "(),a->a", "sub8", 3, 0xb0, 4, 4, CHG_NZVC },
  479. { "cmpa", "(),a", "sub8", 3, 0xb1, 4, 4, CHG_NZVC },
  480. { "sbca", "(),a->a", "sbc8", 3, 0xb2, 4, 4, CHG_NZVC },
  481. { "subd", "(),d->d", "sub16", 3, 0xb3, 6, 6, CHG_NZVC },
  482. { "anda", "(),a->a", "and8", 3, 0xb4, 4, 4, CLR_V_CHG_NZ },
  483. { "bita", "(),a", "and8", 3, 0xb5, 4, 4, CLR_V_CHG_NZ },
  484. { "ldaa", "()->a", "movtst8", 3, 0xb6, 4, 4, CLR_V_CHG_NZ },
  485. { "staa", "a->()", "movtst8", 3, 0xb7, 4, 4, CLR_V_CHG_NZ },
  486. { "eora", "(),a->a", "eor8", 3, 0xb8, 4, 4, CLR_V_CHG_NZ },
  487. { "adca", "(),a->a", "adc8", 3, 0xb9, 4, 4, CHG_HNZVC },
  488. { "oraa", "(),a->a", "or8", 3, 0xba, 4, 4, CLR_V_CHG_NZ },
  489. { "adda", "(),a->a", "add8", 3, 0xbb, 4, 4, CHG_HNZVC },
  490. { "cmpx", "(),x", "sub16", 3, 0xbc, 5, 5, CHG_NZVC },
  491. { "jsr", "&()", "jsr_11_16", 3, 0xbd, 6, 6, CHG_NONE },
  492. { "lds", "()->sp", "movtst16", 3, 0xbe, 5, 5, CLR_V_CHG_NZ },
  493. { "sts", "sp->()", "movtst16", 3, 0xbf, 5, 5, CLR_V_CHG_NZ },
  494. { "subb", "#,b->b", "sub8", 2, 0xc0, 2, 2, CHG_NZVC },
  495. { "cmpb", "#,b", "sub8", 2, 0xc1, 2, 2, CHG_NZVC },
  496. { "sbcb", "#,b->b", "sbc8", 2, 0xc2, 2, 2, CHG_NZVC },
  497. { "addd", "#,d->d", "add16", 3, 0xc3, 4, 4, CHG_NZVC },
  498. { "andb", "#,b->b", "and8", 2, 0xc4, 2, 2, CLR_V_CHG_NZ },
  499. { "bitb", "#,b", "and8", 2, 0xc5, 2, 2, CLR_V_CHG_NZ },
  500. { "ldab", "#->b", "movtst8", 2, 0xc6, 2, 2, CLR_V_CHG_NZ },
  501. { "eorb", "#,b->b", "eor8", 2, 0xc8, 2, 2, CLR_V_CHG_NZ },
  502. { "adcb", "#,b->b", "adc8", 2, 0xc9, 2, 2, CHG_HNZVC },
  503. { "orab", "#,b->b", "or8", 2, 0xca, 2, 2, CLR_V_CHG_NZ },
  504. { "addb", "#,b->b", "add8", 2, 0xcb, 2, 2, CHG_HNZVC },
  505. { "ldd", "#->d", "movtst16", 3, 0xcc, 3, 3, CLR_V_CHG_NZ },
  506. { "page4",0, "page4", 1, 0xcd, 0, 0, CHG_NONE },
  507. { "ldx", "#->x", "movtst16", 3, 0xce, 3, 3, CLR_V_CHG_NZ },
  508. { "stop", 0, 0, 1, 0xcf, 2, 2, CHG_NONE },
  509. { "subb", "*,b->b", "sub8", 2, 0xd0, 3, 3, CHG_NZVC },
  510. { "cmpb", "*,b", "sub8", 2, 0xd1, 3, 3, CHG_NZVC },
  511. { "sbcb", "*,b->b", "sbc8", 2, 0xd2, 3, 3, CHG_NZVC },
  512. { "addd", "*,d->d", "add16", 2, 0xd3, 5, 5, CHG_NZVC },
  513. { "andb", "*,b->b", "and8", 2, 0xd4, 3, 3, CLR_V_CHG_NZ },
  514. { "bitb", "*,b", "and8", 2, 0xd5, 3, 3, CLR_V_CHG_NZ },
  515. { "ldab", "*->b", "movtst8", 2, 0xd6, 3, 3, CLR_V_CHG_NZ },
  516. { "stab", "b->*", "movtst8", 2, 0xd7, 3, 3, CLR_V_CHG_NZ },
  517. { "eorb", "*,b->b", "eor8", 2, 0xd8, 3, 3, CLR_V_CHG_NZ },
  518. { "adcb", "*,b->b", "adc8", 2, 0xd9, 3, 3, CHG_HNZVC },
  519. { "orab", "*,b->b", "or8", 2, 0xda, 3, 3, CLR_V_CHG_NZ },
  520. { "addb", "*,b->b", "add8", 2, 0xdb, 3, 3, CHG_HNZVC },
  521. { "ldd", "*->d", "movtst16", 2, 0xdc, 4, 4, CLR_V_CHG_NZ },
  522. { "std", "d->*", "movtst16", 2, 0xdd, 4, 4, CLR_V_CHG_NZ },
  523. { "ldx", "*->x", "movtst16", 2, 0xde, 4, 4, CLR_V_CHG_NZ },
  524. { "stx", "x->*", "movtst16", 2, 0xdf, 4, 4, CLR_V_CHG_NZ },
  525. { "subb", "(x),b->b", "sub8", 2, 0xe0, 4, 4, CHG_NZVC },
  526. { "cmpb", "(x),b", "sub8", 2, 0xe1, 4, 4, CHG_NZVC },
  527. { "sbcb", "(x),b->b", "sbc8", 2, 0xe2, 4, 4, CHG_NZVC },
  528. { "addd", "(x),d->d", "add16", 2, 0xe3, 6, 6, CHG_NZVC },
  529. { "andb", "(x),b->b", "and8", 2, 0xe4, 4, 4, CLR_V_CHG_NZ },
  530. { "bitb", "(x),b", "and8", 2, 0xe5, 4, 4, CLR_V_CHG_NZ },
  531. { "ldab", "(x)->b", "movtst8", 2, 0xe6, 4, 4, CLR_V_CHG_NZ },
  532. { "stab", "b->(x)", "movtst8", 2, 0xe7, 4, 4, CLR_V_CHG_NZ },
  533. { "eorb", "(x),b->b", "eor8", 2, 0xe8, 4, 4, CLR_V_CHG_NZ },
  534. { "adcb", "(x),b->b", "adc8", 2, 0xe9, 4, 4, CHG_HNZVC },
  535. { "orab", "(x),b->b", "or8", 2, 0xea, 4, 4, CLR_V_CHG_NZ },
  536. { "addb", "(x),b->b", "add8", 2, 0xeb, 4, 4, CHG_HNZVC },
  537. { "ldd", "(x)->d", "movtst16", 2, 0xec, 5, 5, CLR_V_CHG_NZ },
  538. { "std", "d->(x)", "movtst16", 2, 0xed, 5, 5, CLR_V_CHG_NZ },
  539. { "ldx", "(x)->x", "movtst16", 2, 0xee, 5, 5, CLR_V_CHG_NZ },
  540. { "stx", "x->(x)", "movtst16", 2, 0xef, 5, 5, CLR_V_CHG_NZ },
  541. { "subb", "(),b->b", "sub8", 3, 0xf0, 4, 4, CHG_NZVC },
  542. { "cmpb", "(),b", "sub8", 3, 0xf1, 4, 4, CHG_NZVC },
  543. { "sbcb", "(),b->b", "sbc8", 3, 0xf2, 4, 4, CHG_NZVC },
  544. { "addd", "(),d->d", "add16", 3, 0xf3, 6, 6, CHG_NZVC },
  545. { "andb", "(),b->b", "and8", 3, 0xf4, 4, 4, CLR_V_CHG_NZ },
  546. { "bitb", "(),b", "and8", 3, 0xf5, 4, 4, CLR_V_CHG_NZ },
  547. { "ldab", "()->b", "movtst8", 3, 0xf6, 4, 4, CLR_V_CHG_NZ },
  548. { "stab", "b->()", "movtst8", 3, 0xf7, 4, 4, CLR_V_CHG_NZ },
  549. { "eorb", "(),b->b", "eor8", 3, 0xf8, 4, 4, CLR_V_CHG_NZ },
  550. { "adcb", "(),b->b", "eor8", 3, 0xf9, 4, 4, CHG_HNZVC },
  551. { "orab", "(),b->b", "or8", 3, 0xfa, 4, 4, CLR_V_CHG_NZ },
  552. { "addb", "(),b->b", "add8", 3, 0xfb, 4, 4, CHG_HNZVC },
  553. { "ldd", "()->d", "movtst16", 3, 0xfc, 5, 5, CLR_V_CHG_NZ },
  554. { "std", "d->()", "movtst16", 3, 0xfd, 5, 5, CLR_V_CHG_NZ },
  555. { "ldx", "()->x", "movtst16", 3, 0xfe, 5, 5, CLR_V_CHG_NZ },
  556. { "stx", "x->()", "movtst16", 3, 0xff, 5, 5, CLR_V_CHG_NZ }
  557. };
  558. /* Page 2 opcodes */
  559. /*
  560. * { "dex", "x->x", "dec16", 1, 0x00, 5, _M, CHG_NONE },
  561. * Name -+ +----- Insn CCR changes
  562. * Operands ---+ +------------ Max # cycles
  563. * Pattern -----------+ +--------------- Min # cycles
  564. * Size -----------------+ +-------------------- Opcode
  565. */
  566. struct m6811_opcode_def m6811_page2_opcodes[] = {
  567. { "iny", "y->y", "inc16", 2, 0x08, 4, 4, CHG_Z },
  568. { "dey", "y->y", "dec16", 2, 0x09, 4, 4, CHG_Z },
  569. { "bset", "(y),#->(y)","or8", 4, 0x1c, 8, 8, CLR_V_CHG_NZ },
  570. { "bclr", "(y),#->(y)","bclr8", 4, 0x1d, 8, 8, CLR_V_CHG_NZ },
  571. { "brset","(y),#,r", "brset8", 5, 0x1e, 8, 8, CHG_NONE },
  572. { "brclr","(y),#,r", "brclr8", 5, 0x1f, 8, 8, CHG_NONE },
  573. { "tsy", "sp->y", "tsxy16", 2, 0x30, 4, 4, CHG_NONE },
  574. { "tys", "y->sp", "txys16", 2, 0x35, 4, 4, CHG_NONE },
  575. { "puly", "(sp)->y", "mov16", 2, 0x38, 6, 6, CHG_NONE },
  576. { "aby", "b,y->y", "abxy16", 2, 0x3a, 4, 4, CHG_NONE },
  577. { "pshy", "y->(sp)", "mov16", 2, 0x3c, 5, 5, CHG_NONE },
  578. { "neg", "(y)->(y)", "neg8", 3, 0x60, 7, 7, CHG_NZVC },
  579. { "com", "(y)->(y)", "com8", 3, 0x63, 7, 7, SET_C_CLR_V_CHG_NZ},
  580. { "lsr", "(y)->(y)", "lsr8", 3, 0x64, 7, 7, CLR_V_CHG_ZVC },
  581. { "ror", "(y)->(y)", "ror8", 3, 0x66, 7, 7, CHG_NZVC },
  582. { "asr", "(y)->(y)", "asr8", 3, 0x67, 7, 7, CHG_NZVC },
  583. { "asl", "(y)->(y)", "lsl8", 3, 0x68, 7, 7, CHG_NZVC },
  584. { "rol", "(y)->(y)", "rol8", 3, 0x69, 7, 7, CHG_NZVC },
  585. { "dec", "(y)->(y)", "dec8", 3, 0x6a, 7, 7, CHG_NZV },
  586. { "inc", "(y)->(y)", "inc8", 3, 0x6c, 7, 7, CHG_NZV },
  587. { "tst", "(y)", "tst8", 3, 0x6d, 7, 7, CLR_V_CHG_NZ },
  588. { "jmp", "&(y)", "bra", 3, 0x6e, 4, 4, CHG_NONE },
  589. { "clr", "->(y)", "clr8", 3, 0x6f, 7, 7, SET_Z_CLR_NVC },
  590. { "cmpy", "#,y", "sub16", 4, 0x8c, 5, 5, CHG_NZVC },
  591. { "xgdy", "y->y", "xgdxy16", 2, 0x8f, 4, 4, CHG_NONE },
  592. { "cmpy", "*,y", "sub16", 3, 0x9c, 6, 6, CHG_NZVC },
  593. { "suba", "(y),a->a", "sub8", 3, 0xa0, 5, 5, CHG_NZVC },
  594. { "cmpa", "(y),a", "sub8", 3, 0xa1, 5, 5, CHG_NZVC },
  595. { "sbca", "(y),a->a", "sbc8", 3, 0xa2, 5, 5, CHG_NZVC },
  596. { "subd", "(y),d->d", "sub16", 3, 0xa3, 7, 7, CHG_NZVC },
  597. { "anda", "(y),a->a", "and8", 3, 0xa4, 5, 5, CLR_V_CHG_NZ },
  598. { "bita", "(y),a", "and8", 3, 0xa5, 5, 5, CLR_V_CHG_NZ },
  599. { "ldaa", "(y)->a", "movtst8", 3, 0xa6, 5, 5, CLR_V_CHG_NZ },
  600. { "staa", "a->(y)", "movtst8", 3, 0xa7, 5, 5, CLR_V_CHG_NZ },
  601. { "eora", "(y),a->a", "eor8", 3, 0xa8, 5, 5, CLR_V_CHG_NZ },
  602. { "adca", "(y),a->a", "adc8", 3, 0xa9, 5, 5, CHG_HNZVC },
  603. { "oraa", "(y),a->a", "or8", 3, 0xaa, 5, 5, CLR_V_CHG_NZ },
  604. { "adda", "(y),a->a", "add8", 3, 0xab, 5, 5, CHG_HNZVC },
  605. { "cmpy", "(y),y", "sub16", 3, 0xac, 7, 7, CHG_NZVC },
  606. { "jsr", "&(y)", "jsr_11_16", 3, 0xad, 6, 6, CHG_NONE },
  607. { "lds", "(y)->sp", "movtst16", 3, 0xae, 6, 6, CLR_V_CHG_NZ },
  608. { "sts", "sp->(y)", "movtst16", 3, 0xaf, 6, 6, CLR_V_CHG_NZ },
  609. { "cmpy", "(),y", "sub16", 4, 0xbc, 7, 7, CHG_NZVC },
  610. { "ldy", "#->y", "movtst16", 4, 0xce, 4, 4, CLR_V_CHG_NZ },
  611. { "ldy", "*->y", "movtst16", 3, 0xde, 5, 5, CLR_V_CHG_NZ },
  612. { "sty", "y->*", "movtst16", 3, 0xdf, 5, 5, CLR_V_CHG_NZ },
  613. { "subb", "(y),b->b", "sub8", 3, 0xe0, 5, 5, CHG_NZVC },
  614. { "cmpb", "(y),b", "sub8", 3, 0xe1, 5, 5, CHG_NZVC },
  615. { "sbcb", "(y),b->b", "sbc8", 3, 0xe2, 5, 5, CHG_NZVC },
  616. { "addd", "(y),d->d", "add16", 3, 0xe3, 7, 7, CHG_NZVC },
  617. { "andb", "(y),b->b", "and8", 3, 0xe4, 5, 5, CLR_V_CHG_NZ },
  618. { "bitb", "(y),b", "and8", 3, 0xe5, 5, 5, CLR_V_CHG_NZ },
  619. { "ldab", "(y)->b", "movtst8", 3, 0xe6, 5, 5, CLR_V_CHG_NZ },
  620. { "stab", "b->(y)", "movtst8", 3, 0xe7, 5, 5, CLR_V_CHG_NZ },
  621. { "eorb", "(y),b->b", "eor8", 3, 0xe8, 5, 5, CLR_V_CHG_NZ },
  622. { "adcb", "(y),b->b", "adc8", 3, 0xe9, 5, 5, CHG_HNZVC },
  623. { "orab", "(y),b->b", "or8", 3, 0xea, 5, 5, CLR_V_CHG_NZ },
  624. { "addb", "(y),b->b", "add8", 3, 0xeb, 5, 5, CHG_HNZVC },
  625. { "ldd", "(y)->d", "movtst16", 3, 0xec, 6, 6, CLR_V_CHG_NZ },
  626. { "std", "d->(y)", "movtst16", 3, 0xed, 6, 6, CLR_V_CHG_NZ },
  627. { "ldy", "(y)->y", "movtst16", 3, 0xee, 6, 6, CLR_V_CHG_NZ },
  628. { "sty", "y->(y)", "movtst16", 3, 0xef, 6, 6, CLR_V_CHG_NZ },
  629. { "ldy", "()->y", "movtst16", 4, 0xfe, 6, 6, CLR_V_CHG_NZ },
  630. { "sty", "y->()", "movtst16", 4, 0xff, 6, 6, CLR_V_CHG_NZ }
  631. };
  632. /* Page 3 opcodes */
  633. /*
  634. * { "dex", "x->x", "dec16", 1, 0x00, 5, _M, CHG_NONE },
  635. * Name -+ +----- Insn CCR changes
  636. * Operands ---+ +------------ Max # cycles
  637. * Pattern -----------+ +--------------- Min # cycles
  638. * Size -----------------+ +-------------------- Opcode
  639. */
  640. struct m6811_opcode_def m6811_page3_opcodes[] = {
  641. { "cmpd", "#,d", "sub16", 4, 0x83, 5, 5, CHG_NZVC },
  642. { "cmpd", "*,d", "sub16", 3, 0x93, 6, 6, CHG_NZVC },
  643. { "cmpd", "(x),d", "sub16", 3, 0xa3, 7, 7, CHG_NZVC },
  644. { "cmpy", "(x),y", "sub16", 3, 0xac, 7, 7, CHG_NZVC },
  645. { "cmpd", "(),d", "sub16", 4, 0xb3, 7, 7, CHG_NZVC },
  646. { "ldy", "(x)->y", "movtst16", 3, 0xee, 6, 6, CLR_V_CHG_NZ },
  647. { "sty", "y->(x)", "movtst16", 3, 0xef, 6, 6, CLR_V_CHG_NZ }
  648. };
  649. /* Page 4 opcodes */
  650. /*
  651. * { "dex", "x->x", "dec16", 1, 0x00, 5, _M, CHG_NONE },
  652. * Name -+ +----- Insn CCR changes
  653. * Operands ---+ +------------ Max # cycles
  654. * Pattern -----------+ +--------------- Min # cycles
  655. * Size -----------------+ +-------------------- Opcode
  656. */
  657. struct m6811_opcode_def m6811_page4_opcodes[] = {
  658. { "syscall", "", "syscall", 2, 0x03, 6, 6, CHG_NONE },
  659. { "cmpd", "(y),d", "sub16", 3, 0xa3, 7, 7, CHG_NZVC },
  660. { "cmpx", "(y),x", "sub16", 3, 0xac, 7, 7, CHG_NZVC },
  661. { "ldx", "(y)->x", "movtst16", 3, 0xee, 6, 6, CLR_V_CHG_NZ },
  662. { "stx", "x->(y)", "movtst16", 3, 0xef, 6, 6, CLR_V_CHG_NZ }
  663. };
  664. /* 68HC12 opcodes */
  665. /*
  666. * { "dex", "x->x", "dec16", 1, 0x00, 5, _M, CHG_NONE },
  667. * Name -+ +----- Insn CCR changes
  668. * Operands ---+ +------------ Max # cycles
  669. * Pattern -----------+ +--------------- Min # cycles
  670. * Size -----------------+ +-------------------- Opcode
  671. */
  672. struct m6811_opcode_def m6812_page1_opcodes[] = {
  673. { "adca", "#,a->a", "adc8", 2, 0x89, 1, 1, CHG_HNZVC },
  674. { "adca", "*,a->a", "adc8", 2, 0x99, 3, 3, CHG_HNZVC },
  675. { "adca", "(),a->a", "adc8", 3, 0xb9, 3, 3, CHG_HNZVC },
  676. { "adca", "[],a->a", "adc8", 2, 0xa9, 3, 3, CHG_HNZVC },
  677. { "adcb", "#,b->b", "adc8", 2, 0xc9, 1, 1, CHG_HNZVC },
  678. { "adcb", "*,b->b", "adc8", 3, 0xd9, 3, 3, CHG_HNZVC },
  679. { "adcb", "(),b->b", "adc8", 3, 0xf9, 3, 3, CHG_HNZVC },
  680. { "adcb", "[],b->b", "adc8", 2, 0xe9, 3, 3, CHG_HNZVC },
  681. { "adda", "#,a->a", "add8", 2, 0x8b, 1, 1, CHG_HNZVC },
  682. { "adda", "*,a->a", "add8", 3, 0x9b, 3, 3, CHG_HNZVC },
  683. { "adda", "(),a->a", "add8", 3, 0xbb, 3, 3, CHG_HNZVC },
  684. { "adda", "[],a->a", "add8", 2, 0xab, 3, 3, CHG_HNZVC },
  685. { "addb", "#,b->b", "add8", 2, 0xcb, 1, 1, CHG_HNZVC },
  686. { "addb", "*,b->b", "add8", 3, 0xdb, 3, 3, CHG_HNZVC },
  687. { "addb", "(),b->b", "add8", 3, 0xfb, 3, 3, CHG_HNZVC },
  688. { "addb", "[],b->b", "add8", 2, 0xeb, 3, 3, CHG_HNZVC },
  689. { "addd", "#,d->d", "add16", 3, 0xc3, 2, 2, CHG_NZVC },
  690. { "addd", "*,d->d", "add16", 2, 0xd3, 3, 3, CHG_NZVC },
  691. { "addd", "(),d->d", "add16", 3, 0xf3, 3, 3, CHG_NZVC },
  692. { "addd", "[],d->d", "add16", 2, 0xe3, 3, 3, CHG_NZVC },
  693. { "anda", "#,a->a", "and8", 2, 0x84, 1, 1, CLR_V_CHG_NZ },
  694. { "anda", "*,a->a", "and8", 2, 0x94, 3, 3, CLR_V_CHG_NZ },
  695. { "anda", "(),a->a", "and8", 3, 0xb4, 3, 3, CLR_V_CHG_NZ },
  696. { "anda", "[],a->a", "and8", 2, 0xa4, 3, 3, CLR_V_CHG_NZ },
  697. { "andb", "#,b->b", "and8", 2, 0xc4, 1, 1, CLR_V_CHG_NZ },
  698. { "andb", "*,b->b", "and8", 2, 0xd4, 3, 3, CLR_V_CHG_NZ },
  699. { "andb", "(),b->b", "and8", 3, 0xf4, 3, 3, CLR_V_CHG_NZ },
  700. { "andb", "[],b->b", "and8", 2, 0xe4, 3, 3, CLR_V_CHG_NZ },
  701. { "andcc", "#,ccr->ccr", "and8", 2, 0x10, 1, 1, CHG_ALL },
  702. { "asl", "()->()", "lsl8", 3, 0x78, 4, 4, CHG_NZVC },
  703. { "asl", "[]->[]", "lsl8", 2, 0x68, 3, 3, CHG_NZVC },
  704. { "asla", "a->a", "lsl8", 1, 0x48, 1, 1, CHG_NZVC },
  705. { "aslb", "b->b", "lsl8", 1, 0x58, 1, 1, CHG_NZVC },
  706. { "asld", "d->d", "lsl16", 1, 0x59, 1, 1, CHG_NZVC },
  707. { "asr", "()->()", "asr8", 3, 0x77, 4, 4, CHG_NZVC },
  708. { "asr", "[]->[]", "asr8", 2, 0x67, 3, 3, CHG_NZVC },
  709. { "asra", "a->a", "asr8", 1, 0x47, 1, 1, CHG_NZVC },
  710. { "asrb", "b->b", "asr8", 1, 0x57, 1, 1, CHG_NZVC },
  711. { "bcc", "r", 0, 2, 0x24, 1, 3, CHG_NONE },
  712. { "bclr", "*,#->*", "bclr8", 3, 0x4d, 4, 4, CLR_V_CHG_NZ },
  713. { "bclr", "(),#->()", "bclr8", 4, 0x1d, 4, 4, CLR_V_CHG_NZ },
  714. { "bclr", "[],#->[]", "bclr8", 3, 0x0d, 4, 4, CLR_V_CHG_NZ },
  715. { "bcs", "r", 0, 2, 0x25, 1, 3, CHG_NONE },
  716. { "beq", "r", 0, 2, 0x27, 1, 3, CHG_NONE },
  717. { "bge", "r", 0, 2, 0x2c, 1, 3, CHG_NONE },
  718. { "bgnd", 0, 0, 1, 0x00, 5, 5, CHG_NONE },
  719. { "bgt", "r", 0, 2, 0x2e, 1, 3, CHG_NONE },
  720. { "bhi", "r", 0, 2, 0x22, 1, 3, CHG_NONE },
  721. { "bita", "#,a", "and8", 2, 0x85, 1, 1, CLR_V_CHG_NZ },
  722. { "bita", "*,a", "and8", 2, 0x95, 3, 3, CLR_V_CHG_NZ },
  723. { "bita", "(),a", "and8", 3, 0xb5, 3, 3, CLR_V_CHG_NZ },
  724. { "bita", "[],a", "and8", 2, 0xa5, 3, 3, CLR_V_CHG_NZ },
  725. { "bitb", "#,b", "and8", 2, 0xc5, 1, 1, CLR_V_CHG_NZ },
  726. { "bitb", "*,b", "and8", 2, 0xd5, 3, 3, CLR_V_CHG_NZ },
  727. { "bitb", "(),b", "and8", 3, 0xf5, 3, 3, CLR_V_CHG_NZ },
  728. { "bitb", "[],b", "and8", 2, 0xe5, 3, 3, CLR_V_CHG_NZ },
  729. { "ble", "r", 0, 2, 0x2f, 1, 3, CHG_NONE },
  730. { "bls", "r", 0, 2, 0x23, 1, 3, CHG_NONE },
  731. { "blt", "r", 0, 2, 0x2d, 1, 3, CHG_NONE },
  732. { "bmi", "r", 0, 2, 0x2b, 1, 3, CHG_NONE },
  733. { "bne", "r", 0, 2, 0x26, 1, 3, CHG_NONE },
  734. { "bpl", "r", 0, 2, 0x2a, 1, 3, CHG_NONE },
  735. { "bra", "r", 0, 2, 0x20, 1, 3, CHG_NONE },
  736. { "brclr", "*,#,r", "brclr8", 4, 0x4f, 4, 4, CHG_NONE },
  737. { "brclr", "(),#,r", "brclr8", 5, 0x1f, 5, 5, CHG_NONE },
  738. { "brclr", "[],#,r", "brclr8", 4, 0x0f, 4, 4, CHG_NONE },
  739. { "brn", "r", "nop", 2, 0x21, 1, 3, CHG_NONE },
  740. { "brset", "*,#,r", "brset8", 4, 0x4e, 4, 4, CHG_NONE },
  741. { "brset", "(),#,r", "brset8", 5, 0x1e, 5, 5, CHG_NONE },
  742. { "brset", "[],#,r", "brset8", 4, 0x0e, 4, 4, CHG_NONE },
  743. { "bset", "*,#->*", "or8", 3, 0x4c, 4, 4, CLR_V_CHG_NZ },
  744. { "bset", "(),#->()", "or8", 4, 0x1c, 4, 4, CLR_V_CHG_NZ },
  745. { "bset", "[],#->[]", "or8", 3, 0x0c, 4, 4, CLR_V_CHG_NZ },
  746. { "bsr", "r", "jsr_12_16", 2, 0x07, 4, 4, CHG_NONE },
  747. { "bvc", "r", 0, 2, 0x28, 1, 3, CHG_NONE },
  748. { "bvs", "r", 0, 2, 0x29, 1, 3, CHG_NONE },
  749. { "call", "", "call8", 4, 0x4a, 8, 8, CHG_NONE },
  750. { "call", "", "call_ind",2, 0x4b, 8, 8, CHG_NONE },
  751. { "clr", "->()", "clr8", 3, 0x79, 3, 3, SET_Z_CLR_NVC },
  752. { "clr", "->[]", "clr8", 2, 0x69, 2, 2, SET_Z_CLR_NVC },
  753. { "clra", "->a", "clr8", 1, 0x87, 1, 1, SET_Z_CLR_NVC },
  754. { "clrb", "->b", "clr8", 1, 0xc7, 1, 1, SET_Z_CLR_NVC },
  755. { "cpa", "#,a", "sub8", 2, 0x81, 1, 1, CHG_NZVC },
  756. { "cpa", "*,a", "sub8", 2, 0x91, 3, 3, CHG_NZVC },
  757. { "cpa", "(),a", "sub8", 3, 0xb1, 3, 3, CHG_NZVC },
  758. { "cpa", "[],a", "sub8", 2, 0xa1, 3, 3, CHG_NZVC },
  759. { "cpb", "#,b", "sub8", 2, 0xc1, 1, 1, CHG_NZVC },
  760. { "cpb", "*,b", "sub8", 2, 0xd1, 3, 3, CHG_NZVC },
  761. { "cpb", "(),b", "sub8", 3, 0xf1, 3, 3, CHG_NZVC },
  762. { "cpb", "[],b", "sub8", 2, 0xe1, 3, 3, CHG_NZVC },
  763. { "com", "()->()", "com8", 3, 0x71, 4, 4, SET_C_CLR_V_CHG_NZ },
  764. { "com", "[]->[]", "com8", 2, 0x61, 3, 3, SET_C_CLR_V_CHG_NZ },
  765. { "coma", "a->a", "com8", 1, 0x41, 1, 1, SET_C_CLR_V_CHG_NZ },
  766. { "comb", "b->b", "com8", 1, 0x51, 1, 1, SET_C_CLR_V_CHG_NZ },
  767. { "cpd", "#,d", "sub16", 3, 0x8c, 2, 2, CHG_NZVC },
  768. { "cpd", "*,d", "sub16", 2, 0x9c, 3, 3, CHG_NZVC },
  769. { "cpd", "(),d", "sub16", 3, 0xbc, 3, 3, CHG_NZVC },
  770. { "cpd", "[],d", "sub16", 2, 0xac, 3, 3, CHG_NZVC },
  771. { "cps", "#,sp", "sub16", 3, 0x8f, 2, 2, CHG_NZVC },
  772. { "cps", "*,sp", "sub16", 2, 0x9f, 3, 3, CHG_NZVC },
  773. { "cps", "(),sp", "sub16", 3, 0xbf, 3, 3, CHG_NZVC },
  774. { "cps", "[],sp", "sub16", 2, 0xaf, 3, 3, CHG_NZVC },
  775. { "cpx", "#,x", "sub16", 3, 0x8e, 2, 2, CHG_NZVC },
  776. { "cpx", "*,x", "sub16", 2, 0x9e, 3, 3, CHG_NZVC },
  777. { "cpx", "(),x", "sub16", 3, 0xbe, 3, 3, CHG_NZVC },
  778. { "cpx", "[],x", "sub16", 2, 0xae, 3, 3, CHG_NZVC },
  779. { "cpy", "#,y", "sub16", 3, 0x8d, 2, 2, CHG_NZVC },
  780. { "cpy", "*,y", "sub16", 2, 0x9d, 3, 3, CHG_NZVC },
  781. { "cpy", "(),y", "sub16", 3, 0xbd, 3, 3, CHG_NZVC },
  782. { "cpy", "[],y", "sub16", 2, 0xad, 3, 3, CHG_NZVC },
  783. /* dbeq, dbne, ibeq, ibne, tbeq, tbne */
  784. { "dbeq", 0, "dbcc8", 3, 0x04, 3, 3, CHG_NONE },
  785. { "dec", "()->()", "dec8", 3, 0x73, 4, 4, CHG_NZV },
  786. { "dec", "[]->[]", "dec8", 2, 0x63, 3, 3, CHG_NZV },
  787. { "deca", "a->a", "dec8", 1, 0x43, 1, 1, CHG_NZV },
  788. { "decb", "b->b", "dec8", 1, 0x53, 1, 1, CHG_NZV },
  789. { "dex", "x->x", "dec16", 1, 0x09, 1, 1, CHG_Z },
  790. { "dey", "y->y", "dec16", 1, 0x03, 1, 1, CHG_Z },
  791. { "ediv", 0, 0, 1, 0x11, 11, 11, CHG_NZVC },
  792. { "emul", 0, 0, 1, 0x13, 3, 3, CHG_NZC },
  793. { "eora", "#,a->a", "eor8", 2, 0x88, 1, 1, CLR_V_CHG_NZ },
  794. { "eora", "*,a->a", "eor8", 2, 0x98, 3, 3, CLR_V_CHG_NZ },
  795. { "eora", "(),a->a", "eor8", 3, 0xb8, 3, 3, CLR_V_CHG_NZ },
  796. { "eora", "[],a->a", "eor8", 2, 0xa8, 3, 3, CLR_V_CHG_NZ },
  797. { "eorb", "#,b->b", "eor8", 2, 0xc8, 1, 1, CLR_V_CHG_NZ },
  798. { "eorb", "*,b->b", "eor8", 2, 0xd8, 3, 3, CLR_V_CHG_NZ },
  799. { "eorb", "(),b->b", "eor8", 3, 0xf8, 3, 3, CLR_V_CHG_NZ },
  800. { "eorb", "[],b->b", "eor8", 2, 0xe8, 3, 3, CLR_V_CHG_NZ },
  801. /* exg, sex, tfr */
  802. { "exg", "#", "exg8", 2, 0xb7, 1, 1, CHG_NONE },
  803. { "inc", "()->()", "inc8", 3, 0x72, 4, 4, CHG_NZV },
  804. { "inc", "[]->[]", "inc8", 2, 0x62, 3, 3, CHG_NZV },
  805. { "inca", "a->a", "inc8", 1, 0x42, 1, 1, CHG_NZV },
  806. { "incb", "b->b", "inc8", 1, 0x52, 1, 1, CHG_NZV },
  807. { "inx", "x->x", "inc16", 1, 0x08, 1, 1, CHG_Z },
  808. { "iny", "y->y", "inc16", 1, 0x02, 1, 1, CHG_Z },
  809. { "jmp", "&()", "bra", 3, 0x06, 3, 3, CHG_NONE },
  810. { "jmp", "&[]", "bra", 2, 0x05, 3, 3, CHG_NONE },
  811. { "jsr", "*", "jsr_12_16", 2, 0x17, 4, 4, CHG_NONE },
  812. { "jsr", "&()", "jsr_12_16", 3, 0x16, 4, 4, CHG_NONE },
  813. { "jsr", "&[]", "jsr_12_16", 2, 0x15, 4, 4, CHG_NONE },
  814. { "ldaa", "#->a", "movtst8", 2, 0x86, 1, 1, CLR_V_CHG_NZ },
  815. { "ldaa", "*->a", "movtst8", 2, 0x96, 3, 3, CLR_V_CHG_NZ },
  816. { "ldaa", "()->a", "movtst8", 3, 0xb6, 3, 3, CLR_V_CHG_NZ },
  817. { "ldaa", "[]->a", "movtst8", 2, 0xa6, 3, 3, CLR_V_CHG_NZ },
  818. { "ldab", "#->b", "movtst8", 2, 0xc6, 1, 1, CLR_V_CHG_NZ },
  819. { "ldab", "*->b", "movtst8", 2, 0xd6, 3, 3, CLR_V_CHG_NZ },
  820. { "ldab", "()->b", "movtst8", 3, 0xf6, 3, 3, CLR_V_CHG_NZ },
  821. { "ldab", "[]->b", "movtst8", 2, 0xe6, 3, 3, CLR_V_CHG_NZ },
  822. { "ldd", "#->d", "movtst16", 3, 0xcc, 2, 2, CLR_V_CHG_NZ },
  823. { "ldd", "*->d", "movtst16", 2, 0xdc, 3, 3, CLR_V_CHG_NZ },
  824. { "ldd", "()->d", "movtst16", 3, 0xfc, 3, 3, CLR_V_CHG_NZ },
  825. { "ldd", "[]->d", "movtst16", 2, 0xec, 3, 3, CLR_V_CHG_NZ },
  826. { "lds", "#->sp", "movtst16", 3, 0xcf, 2, 2, CLR_V_CHG_NZ },
  827. { "lds", "*->sp", "movtst16", 2, 0xdf, 3, 3, CLR_V_CHG_NZ },
  828. { "lds", "()->sp", "movtst16", 3, 0xff, 3, 3, CLR_V_CHG_NZ },
  829. { "lds", "[]->sp", "movtst16", 2, 0xef, 3, 3, CLR_V_CHG_NZ },
  830. { "ldx", "#->x", "movtst16", 3, 0xce, 2, 2, CLR_V_CHG_NZ },
  831. { "ldx", "*->x", "movtst16", 2, 0xde, 3, 3, CLR_V_CHG_NZ },
  832. { "ldx", "()->x", "movtst16", 3, 0xfe, 3, 3, CLR_V_CHG_NZ },
  833. { "ldx", "[]->x", "movtst16", 2, 0xee, 3, 3, CLR_V_CHG_NZ },
  834. { "ldy", "#->y", "movtst16", 3, 0xcd, 2, 2, CLR_V_CHG_NZ },
  835. { "ldy", "*->y", "movtst16", 2, 0xdd, 3, 3, CLR_V_CHG_NZ },
  836. { "ldy", "()->y", "movtst16", 3, 0xfd, 3, 3, CLR_V_CHG_NZ },
  837. { "ldy", "[]->y", "movtst16", 2, 0xed, 3, 3, CLR_V_CHG_NZ },
  838. { "leas", "&[]->sp", "lea16", 2, 0x1b, 2, 2, CHG_NONE },
  839. { "leax", "&[]->x", "lea16", 2, 0x1a, 2, 2, CHG_NONE },
  840. { "leay", "&[]->y", "lea16", 2, 0x19, 2, 2, CHG_NONE },
  841. { "lsr", "()->()", "lsr8", 3, 0x74, 4, 4, CLR_N_CHG_ZVC },
  842. { "lsr", "[]->[]", "lsr8", 2, 0x64, 3, 3, CLR_N_CHG_ZVC },
  843. { "lsra", "a->a", "lsr8", 1, 0x44, 1, 1, CLR_N_CHG_ZVC },
  844. { "lsrb", "b->b", "lsr8", 1, 0x54, 1, 1, CLR_N_CHG_ZVC },
  845. { "lsrd", "d->d", "lsr16", 1, 0x49, 1, 1, CLR_N_CHG_ZVC },
  846. { "mem", 0, 0, 1, 0x01, 5, 5, CHG_HNZVC },
  847. { "mul", "b,a->d", "mul16", 1, 0x12, 3, 3, CHG_C },
  848. { "neg", "()->()", "neg8", 3, 0x70, 4, 4, CHG_NZVC },
  849. { "neg", "[]->[]", "neg8", 2, 0x60, 3, 3, CHG_NZVC },
  850. { "nega", "a->a", "neg8", 1, 0x40, 1, 1, CHG_NZVC },
  851. { "negb", "b->b", "neg8", 1, 0x50, 1, 1, CHG_NZVC },
  852. { "nop", "", "nop", 1, 0xa7, 1, 1, CHG_NONE },
  853. { "oraa", "#,a->a", "or8", 2, 0x8a, 1, 1, CLR_V_CHG_NZ },
  854. { "oraa", "*,a->a", "or8", 2, 0x9a, 3, 3, CLR_V_CHG_NZ },
  855. { "oraa", "(),a->a", "or8", 3, 0xba, 3, 3, CLR_V_CHG_NZ },
  856. { "oraa", "[],a->a", "or8", 2, 0xaa, 3, 3, CLR_V_CHG_NZ },
  857. { "orab", "#,b->b", "or8", 2, 0xca, 1, 1, CLR_V_CHG_NZ },
  858. { "orab", "*,b->b", "or8", 2, 0xda, 3, 3, CLR_V_CHG_NZ },
  859. { "orab", "(),b->b", "or8", 3, 0xfa, 3, 3, CLR_V_CHG_NZ },
  860. { "orab", "[],b->b", "or8", 2, 0xea, 3, 3, CLR_V_CHG_NZ },
  861. { "orcc", "#,ccr->ccr", "or8", 2, 0x14, 1, 1, CHG_ALL },
  862. { "page2", 0, "page2", 1, 0x18, 0, 0, CHG_NONE },
  863. { "psha", "a->(sp)", "mov8", 1, 0x36, 2, 2, CHG_NONE },
  864. { "pshb", "b->(sp)", "mov8", 1, 0x37, 2, 2, CHG_NONE },
  865. { "pshc", "ccr->(sp)", "mov8", 1, 0x39, 2, 2, CHG_NONE },
  866. { "pshd", "d->(sp)", "mov16", 1, 0x3b, 2, 2, CHG_NONE },
  867. { "pshx", "x->(sp)", "mov16", 1, 0x34, 2, 2, CHG_NONE },
  868. { "pshy", "y->(sp)", "mov16", 1, 0x35, 2, 2, CHG_NONE },
  869. { "pula", "(sp)->a", "mov8", 1, 0x32, 3, 3, CHG_NONE },
  870. { "pulb", "(sp)->b", "mov8", 1, 0x33, 3, 3, CHG_NONE },
  871. { "pulc", "(sp)->ccr", "mov8", 1, 0x38, 3, 3, CHG_ALL },
  872. { "puld", "(sp)->d", "mov16", 1, 0x3a, 3, 3, CHG_NONE },
  873. { "pulx", "(sp)->x", "mov16", 1, 0x30, 3, 3, CHG_NONE },
  874. { "puly", "(sp)->y", "mov16", 1, 0x31, 3, 3, CHG_NONE },
  875. { "rol", "()->()", "rol8", 3, 0x75, 4, 4, CHG_NZVC },
  876. { "rol", "[]->[]", "rol8", 2, 0x65, 3, 3, CHG_NZVC },
  877. { "rola", "a->a", "rol8", 1, 0x45, 1, 1, CHG_NZVC },
  878. { "rolb", "b->b", "rol8", 1, 0x55, 1, 1, CHG_NZVC },
  879. { "ror", "()->()", "ror8", 3, 0x76, 4, 4, CHG_NZVC },
  880. { "ror", "[]->[]", "ror8", 2, 0x66, 3, 3, CHG_NZVC },
  881. { "rora", "a->a", "ror8", 1, 0x46, 1, 1, CHG_NZVC },
  882. { "rorb", "b->b", "ror8", 1, 0x56, 1, 1, CHG_NZVC },
  883. { "rtc", 0, 0, 1, 0x0a, 6, 6, CHG_NONE },
  884. { "rti", 0, "rti12", 1, 0x0b, 8, 10, CHG_ALL},
  885. { "rts", 0, "rts12", 1, 0x3d, 5, 5, CHG_NONE },
  886. { "sbca", "#,a->a", "sbc8", 2, 0x82, 1, 1, CHG_NZVC },
  887. { "sbca", "*,a->a", "sbc8", 2, 0x92, 3, 3, CHG_NZVC },
  888. { "sbca", "(),a->a", "sbc8", 3, 0xb2, 3, 3, CHG_NZVC },
  889. { "sbca", "[],a->a", "sbc8", 2, 0xa2, 3, 3, CHG_NZVC },
  890. { "sbcb", "#,b->b", "sbc8", 2, 0xc2, 1, 1, CHG_NZVC },
  891. { "sbcb", "*,b->b", "sbc8", 2, 0xd2, 3, 3, CHG_NZVC },
  892. { "sbcb", "(),b->b", "sbc8", 3, 0xf2, 3, 3, CHG_NZVC },
  893. { "sbcb", "[],b->b", "sbc8", 2, 0xe2, 3, 3, CHG_NZVC },
  894. { "staa", "a->*", "movtst8", 2, 0x5a, 2, 2, CLR_V_CHG_NZ },
  895. { "staa", "a->()", "movtst8", 3, 0x7a, 3, 3, CLR_V_CHG_NZ },
  896. { "staa", "a->[]", "movtst8", 2, 0x6a, 2, 2, CLR_V_CHG_NZ },
  897. { "stab", "b->*", "movtst8", 2, 0x5b, 2, 2, CLR_V_CHG_NZ },
  898. { "stab", "b->()", "movtst8", 3, 0x7b, 3, 3, CLR_V_CHG_NZ },
  899. { "stab", "b->[]", "movtst8", 2, 0x6b, 2, 2, CLR_V_CHG_NZ },
  900. { "std", "d->*", "movtst16", 2, 0x5c, 2, 2, CLR_V_CHG_NZ },
  901. { "std", "d->()", "movtst16", 3, 0x7c, 3, 3, CLR_V_CHG_NZ },
  902. { "std", "d->[]", "movtst16", 2, 0x6c, 2, 2, CLR_V_CHG_NZ },
  903. { "sts", "sp->*", "movtst16", 2, 0x5f, 2, 2, CLR_V_CHG_NZ },
  904. { "sts", "sp->()", "movtst16", 3, 0x7f, 3, 3, CLR_V_CHG_NZ },
  905. { "sts", "sp->[]", "movtst16", 2, 0x6f, 2, 2, CLR_V_CHG_NZ },
  906. { "stx", "x->*", "movtst16", 2, 0x5e, 2, 2, CLR_V_CHG_NZ },
  907. { "stx", "x->()", "movtst16", 3, 0x7e, 3, 3, CLR_V_CHG_NZ },
  908. { "stx", "x->[]", "movtst16", 2, 0x6e, 2, 2, CLR_V_CHG_NZ },
  909. { "sty", "y->*", "movtst16", 2, 0x5d, 2, 2, CLR_V_CHG_NZ },
  910. { "sty", "y->()", "movtst16", 3, 0x7d, 3, 3, CLR_V_CHG_NZ },
  911. { "sty", "y->[]", "movtst16", 2, 0x6d, 2, 2, CLR_V_CHG_NZ },
  912. { "suba", "#,a->a", "sub8", 2, 0x80, 1, 1, CHG_NZVC },
  913. { "suba", "*,a->a", "sub8", 2, 0x90, 3, 3, CHG_NZVC },
  914. { "suba", "(),a->a", "sub8", 3, 0xb0, 3, 3, CHG_NZVC },
  915. { "suba", "[],a->a", "sub8", 2, 0xa0, 3, 3, CHG_NZVC },
  916. { "subb", "#,b->b", "sub8", 2, 0xc0, 1, 1, CHG_NZVC },
  917. { "subb", "*,b->b", "sub8", 2, 0xd0, 3, 3, CHG_NZVC },
  918. { "subb", "(),b->b", "sub8", 3, 0xf0, 3, 3, CHG_NZVC },
  919. { "subb", "[],b->b", "sub8", 2, 0xe0, 3, 3, CHG_NZVC },
  920. { "subd", "#,d->d", "sub16", 3, 0x83, 2, 2, CHG_NZVC },
  921. { "subd", "*,d->d", "sub16", 2, 0x93, 3, 3, CHG_NZVC },
  922. { "subd", "(),d->d", "sub16", 3, 0xb3, 3, 3, CHG_NZVC },
  923. { "subd", "[],d->d", "sub16", 2, 0xa3, 3, 3, CHG_NZVC },
  924. { "swi", 0, 0, 1, 0x3f, 9, 9, CHG_NONE },
  925. { "tst", "()", "tst8", 3, 0xf7, 3, 3, CLR_VC_CHG_NZ },
  926. { "tst", "[]", "tst8", 2, 0xe7, 3, 3, CLR_VC_CHG_NZ },
  927. { "tsta", "a", "tst8", 1, 0x97, 1, 1, CLR_VC_CHG_NZ },
  928. { "tstb", "b", "tst8", 1, 0xd7, 1, 1, CLR_VC_CHG_NZ },
  929. { "wai", 0, 0, 1, 0x3e, 8, _M, CHG_NONE }
  930. };
  931. struct m6811_opcode_def m6812_page2_opcodes[] = {
  932. { "cba", "b,a", "sub8", 2, 0x17, 2, 2, CHG_NZVC },
  933. /* After 'daa', the Z flag is undefined. Mark it as changed. */
  934. { "daa", 0, "daa8", 2, 0x07, 3, 3, CHG_NZVC },
  935. { "edivs", 0, 0, 2, 0x14, 12, 12, CHG_NZVC },
  936. { "emacs", 0, 0, 2, 0x12, 13, 13, CHG_NZVC },
  937. { "emaxd", "[],d->d", "max16", 3, 0x1a, 4, 4, CHG_NZVC },
  938. { "emaxm", "[],d->[]", "max16", 3, 0x1e, 4, 4, CHG_NZVC },
  939. { "emind", "[],d->d", "min16", 3, 0x1b, 4, 4, CHG_NZVC },
  940. { "eminm", "[],d->[]", "min16", 3, 0x1f, 4, 4, CHG_NZVC },
  941. { "emuls", 0, 0, 2, 0x13, 3, 3, CHG_NZC },
  942. { "etbl", "[]", "tbl16", 3, 0x3f, 10, 10, CHG_NZC },
  943. { "fdiv", "x,d->x", "fdiv16", 2, 0x11, 12, 12, CHG_ZVC },
  944. { "idiv", "x,d->x", "idiv16", 2, 0x10, 12, 12, CLR_V_CHG_ZC },
  945. { "idivs", 0, 0, 2, 0x15, 12, 12, CHG_NZVC },
  946. { "lbcc", "R", "bcc", 4, 0x24, 3, 4, CHG_NONE },
  947. { "lbcs", "R", "bcs", 4, 0x25, 3, 4, CHG_NONE },
  948. { "lbeq", "R", "beq", 4, 0x27, 3, 4, CHG_NONE },
  949. { "lbge", "R", "bge", 4, 0x2c, 3, 4, CHG_NONE },
  950. { "lbgt", "R", "bgt", 4, 0x2e, 3, 4, CHG_NONE },
  951. { "lbhi", "R", "bhi", 4, 0x22, 3, 4, CHG_NONE },
  952. { "lble", "R", "ble", 4, 0x2f, 3, 4, CHG_NONE },
  953. { "lbls", "R", "bls", 4, 0x23, 3, 4, CHG_NONE },
  954. { "lblt", "R", "blt", 4, 0x2d, 3, 4, CHG_NONE },
  955. { "lbmi", "R", "bmi", 4, 0x2b, 3, 4, CHG_NONE },
  956. { "lbne", "R", "bne", 4, 0x26, 3, 4, CHG_NONE },
  957. { "lbpl", "R", "bpl", 4, 0x2a, 3, 4, CHG_NONE },
  958. { "lbra", "R", "bra", 4, 0x20, 4, 4, CHG_NONE },
  959. { "lbrn", "R", "nop", 4, 0x21, 3, 3, CHG_NONE },
  960. { "lbvc", "R", "bvc", 4, 0x28, 3, 4, CHG_NONE },
  961. { "lbvs", "R", "bvs", 4, 0x29, 3, 4, CHG_NONE },
  962. { "maxa", "[],a->a", "max8", 3, 0x18, 4, 4, CHG_NZVC },
  963. { "maxm", "[],a->[]", "max8", 3, 0x1c, 4, 4, CHG_NZVC },
  964. { "mina", "[],a->a", "min8", 3, 0x19, 4, 4, CHG_NZVC },
  965. { "minm", "[],a->[]", "min8", 3, 0x1d, 4, 4, CHG_NZVC },
  966. { "movb", 0, "move8", 5, 0x0b, 4, 4, CHG_NONE },
  967. { "movb", 0, "move8", 4, 0x08, 4, 4, CHG_NONE },
  968. { "movb", 0, "move8", 6, 0x0c, 6, 6, CHG_NONE },
  969. { "movb", 0, "move8", 5, 0x09, 5, 5, CHG_NONE },
  970. { "movb", 0, "move8", 5, 0x0d, 5, 5, CHG_NONE },
  971. { "movb", 0, "move8", 4, 0x0a, 5, 5, CHG_NONE },
  972. { "movw", 0, "move16", 6, 0x03, 5, 5, CHG_NONE },
  973. { "movw", 0, "move16", 5, 0x00, 4, 4, CHG_NONE },
  974. { "movw", 0, "move16", 6, 0x04, 6, 6, CHG_NONE },
  975. { "movw", 0, "move16", 5, 0x01, 5, 5, CHG_NONE },
  976. { "movw", 0, "move16", 5, 0x05, 5, 5, CHG_NONE },
  977. { "movw", 0, "move16", 4, 0x02, 5, 5, CHG_NONE },
  978. { "rev", 0, 0, 2, 0x3a, _M, _M, CHG_HNZVC },
  979. { "revw", 0, 0, 2, 0x3b, _M, _M, CHG_HNZVC },
  980. { "sba", "b,a->a", "sub8", 2, 0x16, 2, 2, CHG_NZVC },
  981. { "stop", 0, 0, 2, 0x3e, 2, 9, CHG_NONE },
  982. { "tab", "a->b", "movtst8", 2, 0x0e, 2, 2, CLR_V_CHG_NZ },
  983. { "tba", "b->a", "movtst8", 2, 0x0f, 2, 2, CLR_V_CHG_NZ },
  984. { "wav", 0, 0, 2, 0x3c, 8, _M, SET_Z_CHG_HNVC }
  985. };
  986. void fatal_error (const struct m6811_opcode_def*, const char*, ...);
  987. void print (FILE*, int, const char*,...);
  988. int gen_fetch_operands (FILE*, int, const struct m6811_opcode_def*,
  989. const char*);
  990. void gen_save_result (FILE*, int, const struct m6811_opcode_def*,
  991. int, const char*);
  992. const struct m6811_opcode_pattern*
  993. find_opcode_pattern (const struct m6811_opcode_def*);
  994. void gen_interp (FILE*, int, const struct m6811_opcode_def*);
  995. void gen_interpreter_for_table (FILE*, int,
  996. const struct m6811_opcode_def*,
  997. int, const char*);
  998. void gen_interpreter (FILE*);
  999. static int indent_level = 2;
  1000. static int current_insn_size = 0;
  1001. /* Fatal error message and exit. This method is called when an inconsistency
  1002. is detected in the generation table. */
  1003. void
  1004. fatal_error (const struct m6811_opcode_def *opcode, const char *msg, ...)
  1005. {
  1006. va_list argp;
  1007. fprintf (stderr, "Fatal error: ");
  1008. va_start (argp, msg);
  1009. vfprintf (stderr, msg, argp);
  1010. va_end (argp);
  1011. fprintf (stderr, "\n");
  1012. if (opcode)
  1013. {
  1014. fprintf (stderr, "Opcode: 0x%02x %s %s\n",
  1015. opcode->insn_code,
  1016. opcode->name ? opcode->name : "(null)",
  1017. opcode->operands ? opcode->operands : "(null)");
  1018. }
  1019. exit (1);
  1020. }
  1021. /* Format and pretty print for the code generation. (printf like format). */
  1022. void
  1023. print (FILE *fp, int col, const char *msg, ...)
  1024. {
  1025. va_list argp;
  1026. char buf[1024];
  1027. int cur_col = -1;
  1028. int i;
  1029. /* Format in a buffer. */
  1030. va_start (argp, msg);
  1031. vsprintf (buf, msg, argp);
  1032. va_end (argp);
  1033. /* Basic pretty print:
  1034. - Every line is indented at column 'col',
  1035. - Indentation is updated when '{' and '}' are found,
  1036. - Indentation is incremented by the special character '@' (not displayed).
  1037. - New lines inserted automatically after ';' */
  1038. for (i = 0; buf[i]; i++)
  1039. {
  1040. if (buf[i] == '{')
  1041. col += indent_level;
  1042. else if (buf[i] == '}')
  1043. col -= indent_level;
  1044. else if (buf[i] == '@')
  1045. {
  1046. col += indent_level;
  1047. continue;
  1048. }
  1049. if (cur_col == -1 && buf[i] != ' ' && buf[i] != '\t' && buf[i] != '\n')
  1050. {
  1051. cur_col = 0;
  1052. while (cur_col < col)
  1053. {
  1054. fputc (' ', fp);
  1055. cur_col++;
  1056. }
  1057. }
  1058. if (buf[i] == '}')
  1059. col -= indent_level;
  1060. else if (buf[i] == '{')
  1061. col += indent_level;
  1062. else if (buf[i] == '\n')
  1063. cur_col = -1;
  1064. if (cur_col != -1 || buf[i] == '\n')
  1065. fputc (buf[i], fp);
  1066. if (buf[i] == ';')
  1067. {
  1068. fputc ('\n', fp);
  1069. cur_col = -1;
  1070. }
  1071. }
  1072. }
  1073. /* Generate the code to obtain the operands before execution of the
  1074. instruction. Operands are copied in local variables. This allows to
  1075. have the same instruction pattern and different operand formats.
  1076. There is a maximum of 3 variables:
  1077. 8-bits 16-bits
  1078. 1st operand: src8 src16
  1079. 2nd operand: dst8 dst16
  1080. alt operand: addr addr
  1081. The operand string is interpreted as follows:
  1082. a Copy A register in the local 8-bits variable.
  1083. b " B "
  1084. ccr " ccr "
  1085. d " D " " " 16-bits variable.
  1086. x " X "
  1087. y " Y "
  1088. sp " SP "
  1089. pc " PC "
  1090. * 68HC11 page0 memory pointer.
  1091. Get 8-bits page0 offset from program, set up 'addr' local
  1092. variable to refer to the location in page0.
  1093. Copy the 8/16-bits value pointed to by 'addr' in a 8/16-bits variable.
  1094. (x) 68HC11 indirect access with X register.
  1095. Get 8-bits unsigned offset from program, set up 'addr' = X + offset.
  1096. Copy the 8/16-bits value pointed to by 'addr' in a 8/16-bits variable.
  1097. (y) Same as (x) with Y register.
  1098. () 68HC11 extended address mode (global variable).
  1099. Get 16-bits address from program and set 'addr'.
  1100. Copy the 8/16-bits value pointed to by 'addr' in a 8/16-bits variable.
  1101. [] 68HC12 indexed addressing mode
  1102. (sp) Pop
  1103. Pop a 8/16-bits value from stack and set in a 8/16-bits variable.
  1104. r Relative branch
  1105. Get 8-bits relative branch, compute absolute address and set 'addr'
  1106. # 68HC11 immediate value
  1107. Get a 8/16-bits value from program and set a 8/16-bits variable.
  1108. &(x)
  1109. &(y)
  1110. &() Similar to (x), (y) and () except that we don't read the
  1111. value pointed to by 'addr' (ie, only 'addr' is setup). Used by jmp/jsr.
  1112. &[] Similar to [] but don't read the value pointed to by the address.
  1113. , Operand separator.
  1114. - End of input operands.
  1115. Example:
  1116. (x),a->a addr = x + (uint16_t) (fetch8 (cpu));
  1117. src8 = a
  1118. *,#,r addr = (uint16_t) (fetch8 (cpu)) <- Temporary 'addr'
  1119. src8 = read_mem8 (cpu, addr)
  1120. dst8 = fetch8 (cpu)
  1121. addr = fetch_relbranch (cpu) <- Final 'addr'
  1122. Returns 1 if the 'addr' operand is set, 0 otherwise. */
  1123. int
  1124. gen_fetch_operands (FILE *fp, int col,
  1125. const struct m6811_opcode_def *opcode,
  1126. const char *operand_size)
  1127. {
  1128. static char *vars[2] = {
  1129. "src",
  1130. "dst"
  1131. };
  1132. char c;
  1133. int addr_set = 0;
  1134. int cur_var = 0;
  1135. const char *operands = opcode->operands;
  1136. if (operands == 0)
  1137. operands = "";
  1138. while ((c = *operands++) != 0)
  1139. {
  1140. switch (c)
  1141. {
  1142. case 'a':
  1143. if (cur_var >= 2)
  1144. fatal_error (opcode, "Too many locals");
  1145. print (fp, col, "%s8 = cpu_get_a (cpu);", vars[cur_var]);
  1146. break;
  1147. case 'b':
  1148. if (cur_var >= 2)
  1149. fatal_error (opcode, "Too many locals");
  1150. print (fp, col, "%s8 = cpu_get_b (cpu);", vars[cur_var]);
  1151. break;
  1152. case 'd':
  1153. if (cur_var >= 2)
  1154. fatal_error (opcode, "Too many locals");
  1155. print (fp, col, "%s16 = cpu_get_d (cpu);", vars[cur_var]);
  1156. break;
  1157. case 'x':
  1158. if (cur_var >= 2)
  1159. fatal_error (opcode, "Too many locals");
  1160. print (fp, col, "%s16 = cpu_get_x (cpu);", vars[cur_var]);
  1161. break;
  1162. case 'y':
  1163. if (cur_var >= 2)
  1164. fatal_error (opcode, "Too many locals");
  1165. print (fp, col, "%s16 = cpu_get_y (cpu);", vars[cur_var]);
  1166. break;
  1167. case '*':
  1168. if (cur_var >= 2)
  1169. fatal_error (opcode, "Too many locals");
  1170. if (addr_set)
  1171. fatal_error (opcode, "Wrong use of '*', 'addr' already used");
  1172. addr_set = 1;
  1173. current_insn_size += 1;
  1174. print (fp, col, "addr = (uint16_t) cpu_fetch8 (cpu);");
  1175. print (fp, col, "%s%s = memory_read%s (cpu, addr);",
  1176. vars[cur_var], operand_size, operand_size);
  1177. break;
  1178. case '&':
  1179. if (addr_set)
  1180. fatal_error (opcode, "Wrong use of '&', 'addr' already used");
  1181. addr_set = 1;
  1182. if (strncmp (operands, "(x)", 3) == 0)
  1183. {
  1184. current_insn_size += 1;
  1185. print (fp, col, "addr = cpu_get_x (cpu) + (uint16_t) cpu_fetch8 (cpu);");
  1186. operands += 3;
  1187. }
  1188. else if (strncmp (operands, "(y)", 3) == 0)
  1189. {
  1190. current_insn_size += 1;
  1191. print (fp, col, "addr = cpu_get_y (cpu) + (uint16_t) cpu_fetch8 (cpu);");
  1192. operands += 3;
  1193. }
  1194. else if (strncmp (operands, "()", 2) == 0)
  1195. {
  1196. current_insn_size += 2;
  1197. print (fp, col, "addr = cpu_fetch16 (cpu);");
  1198. operands += 2;
  1199. }
  1200. else if (strncmp (operands, "[]", 2) == 0)
  1201. {
  1202. current_insn_size += 1;
  1203. print (fp, col, "addr = cpu_get_indexed_operand_addr (cpu, 0);");
  1204. operands += 2;
  1205. }
  1206. else
  1207. {
  1208. fatal_error (opcode, "Unknown operand");
  1209. }
  1210. break;
  1211. case '(':
  1212. if (cur_var >= 2)
  1213. fatal_error (opcode, "Too many locals");
  1214. if (addr_set)
  1215. fatal_error (opcode, "Wrong use of '(', 'addr' already used");
  1216. if (strncmp (operands, "x)", 2) == 0)
  1217. {
  1218. addr_set = 1;
  1219. current_insn_size += 1;
  1220. print (fp, col, "addr = cpu_get_x (cpu) + (uint16_t) cpu_fetch8 (cpu);");
  1221. print (fp, col, "%s%s = memory_read%s (cpu, addr);",
  1222. vars[cur_var], operand_size, operand_size);
  1223. operands += 2;
  1224. }
  1225. else if (strncmp (operands, "y)", 2) == 0)
  1226. {
  1227. addr_set = 1;
  1228. current_insn_size += 1;
  1229. print (fp, col, "addr = cpu_get_y (cpu) + (uint16_t) cpu_fetch8 (cpu);");
  1230. print (fp, col, "%s%s = memory_read%s (cpu, addr);",
  1231. vars[cur_var], operand_size, operand_size);
  1232. operands += 2;
  1233. }
  1234. else if (strncmp (operands, ")", 1) == 0)
  1235. {
  1236. addr_set = 1;
  1237. current_insn_size += 2;
  1238. print (fp, col, "addr = cpu_fetch16 (cpu);");
  1239. print (fp, col, "%s%s = memory_read%s (cpu, addr);",
  1240. vars[cur_var], operand_size, operand_size);
  1241. operands++;
  1242. }
  1243. else if (strncmp (operands, "@)", 2) == 0)
  1244. {
  1245. current_insn_size += 2;
  1246. print (fp, col, "addr = cpu_fetch16 (cpu);");
  1247. print (fp, col, "%s%s = memory_read%s (cpu, addr);",
  1248. vars[cur_var], operand_size, operand_size);
  1249. operands += 2;
  1250. }
  1251. else if (strncmp (operands, "sp)", 3) == 0)
  1252. {
  1253. print (fp, col, "%s%s = cpu_%s_pop_uint%s (cpu);",
  1254. vars[cur_var], operand_size,
  1255. cpu_type == cpu6811 ? "m68hc11" : "m68hc12",
  1256. operand_size);
  1257. operands += 3;
  1258. }
  1259. else
  1260. {
  1261. fatal_error (opcode, "Unknown operand");
  1262. }
  1263. break;
  1264. case '[':
  1265. if (cur_var >= 2)
  1266. fatal_error (opcode, "Too many locals");
  1267. if (addr_set)
  1268. fatal_error (opcode, "Wrong use of '[', 'addr' already used");
  1269. if (strncmp (operands, "]", 1) == 0)
  1270. {
  1271. addr_set = 1;
  1272. current_insn_size += 1;
  1273. print (fp, col, "addr = cpu_get_indexed_operand_addr (cpu,0);");
  1274. print (fp, col, "%s%s = memory_read%s (cpu, addr);",
  1275. vars[cur_var], operand_size, operand_size);
  1276. operands += 1;
  1277. }
  1278. #if 0 /* This code is never executed (see strncmp above), but it has not been
  1279. removed because it may be that there is a typo in strncmp test below. */
  1280. else if (strncmp (operands, "]", 1) == 0)
  1281. {
  1282. current_insn_size += 1;
  1283. print (fp, col, "%s%s = cpu_get_indexed_operand%s (cpu,0);",
  1284. vars[cur_var], operand_size, operand_size);
  1285. operands += 1;
  1286. }
  1287. #endif
  1288. else
  1289. {
  1290. fatal_error (opcode, "Unknown operand");
  1291. }
  1292. break;
  1293. case '{':
  1294. if (cur_var >= 2)
  1295. fatal_error (opcode, "Too many locals");
  1296. if (addr_set)
  1297. fatal_error (opcode, "Wrong use of '{', 'addr' already used");
  1298. if (strncmp (operands, "}", 1) == 0)
  1299. {
  1300. current_insn_size += 1;
  1301. print (fp, col, "%s%s = cpu_get_indexed_operand%s (cpu, 1);",
  1302. vars[cur_var], operand_size, operand_size);
  1303. operands += 1;
  1304. }
  1305. else
  1306. {
  1307. fatal_error (opcode, "Unknown operand");
  1308. }
  1309. break;
  1310. case 's':
  1311. if (cur_var >= 2)
  1312. fatal_error (opcode, "Too many locals");
  1313. if (strncmp (operands, "p", 1) == 0)
  1314. {
  1315. print (fp, col, "%s16 = cpu_get_sp (cpu);", vars[cur_var]);
  1316. operands++;
  1317. }
  1318. else
  1319. {
  1320. fatal_error (opcode, "Unknown operands");
  1321. }
  1322. break;
  1323. case 'c':
  1324. if (strncmp (operands, "cr", 2) == 0)
  1325. {
  1326. print (fp, col, "%s8 = cpu_get_ccr (cpu);", vars[cur_var]);
  1327. operands += 2;
  1328. }
  1329. else
  1330. {
  1331. fatal_error (opcode, "Unknown operands");
  1332. }
  1333. break;
  1334. case 'r':
  1335. if (addr_set && cur_var != 2)
  1336. fatal_error (opcode, "Wrong use of 'r'");
  1337. addr_set = 1;
  1338. current_insn_size += 1;
  1339. print (fp, col, "addr = cpu_fetch_relbranch (cpu);");
  1340. break;
  1341. case 'R':
  1342. if (addr_set && cur_var != 2)
  1343. fatal_error (opcode, "Wrong use of 'R'");
  1344. addr_set = 1;
  1345. current_insn_size += 2;
  1346. print (fp, col, "addr = cpu_fetch_relbranch16 (cpu);");
  1347. break;
  1348. case '#':
  1349. if (strcmp (operand_size, "8") == 0)
  1350. {
  1351. current_insn_size += 1;
  1352. }
  1353. else
  1354. {
  1355. current_insn_size += 2;
  1356. }
  1357. print (fp, col, "%s%s = cpu_fetch%s (cpu);", vars[cur_var],
  1358. operand_size, operand_size);
  1359. break;
  1360. case ',':
  1361. cur_var ++;
  1362. break;
  1363. case '-':
  1364. return addr_set;
  1365. default:
  1366. fatal_error (opcode, "Invalid operands");
  1367. break;
  1368. }
  1369. }
  1370. return addr_set;
  1371. }
  1372. /* Generate the code to save the instruction result. The result is in
  1373. a local variable: either 'dst8' or 'dst16'.
  1374. There may be only one result. Instructions with 2 results (ie idiv
  1375. and fdiv), take care of saving the first value.
  1376. The operand string is the same as for 'gen_fetch_operands'.
  1377. Everything before '->' is ignored. If the '->' is not found, it
  1378. is assumed that there is nothing to save. After '->', the operand
  1379. string is interpreted as follows:
  1380. a Save 'dst8' in A register
  1381. b " B "
  1382. ccr " CCR "
  1383. d " 'dst16' D "
  1384. x " X "
  1385. y " Y "
  1386. sp " SP "
  1387. * 68HC11 page0 memory pointer.
  1388. (x) 68HC11 indirect access with X register.
  1389. (y) Same as (x) with Y register.
  1390. () 68HC11 extended address mode (global variable).
  1391. For these modes, if they were used as an input operand,
  1392. the 'addr' variable contains the address of memory where
  1393. the result must be saved.
  1394. If they were not used an input operand, 'addr' is computed
  1395. (as in gen_fetch_operands()), and the result is saved.
  1396. [] 68HC12 indexed indirect
  1397. (sp) Push
  1398. Push the 8/16-bits result on the stack. */
  1399. void
  1400. gen_save_result (FILE *fp, int col,
  1401. const struct m6811_opcode_def *opcode,
  1402. int addr_set,
  1403. const char *operand_size)
  1404. {
  1405. char c;
  1406. const char *operands = opcode->operands;
  1407. /* When the result is saved, 'result_size' is a string which
  1408. indicates the size of the saved result ("8" or "16"). This
  1409. is a sanity check with 'operand_size' to detect inconsistencies
  1410. in the different tables. */
  1411. const char *result_size = 0;
  1412. if (operands == 0)
  1413. operands = "";
  1414. operands = strchr (operands, '-');
  1415. if (operands == 0)
  1416. return;
  1417. operands++;
  1418. if (*operands++ != '>')
  1419. {
  1420. fatal_error (opcode, "Invalid operand");
  1421. }
  1422. c = *operands++;
  1423. switch (c)
  1424. {
  1425. case 'a':
  1426. result_size = "8";
  1427. print (fp, col, "cpu_set_a (cpu, dst8);");
  1428. break;
  1429. case 'b':
  1430. result_size = "8";
  1431. print (fp, col, "cpu_set_b (cpu, dst8);");
  1432. break;
  1433. case 'd':
  1434. result_size = "16";
  1435. print (fp, col, "cpu_set_d (cpu, dst16);");
  1436. break;
  1437. case 'x':
  1438. result_size = "16";
  1439. print (fp, col, "cpu_set_x (cpu, dst16);");
  1440. break;
  1441. case 'y':
  1442. result_size = "16";
  1443. print (fp, col, "cpu_set_y (cpu, dst16);");
  1444. break;
  1445. case '*':
  1446. if (addr_set == 0)
  1447. {
  1448. current_insn_size += 1;
  1449. print (fp, col, "addr = (uint16_t) cpu_fetch8 (cpu);");
  1450. }
  1451. result_size = operand_size;
  1452. print (fp, col, "memory_write%s (cpu, addr, dst%s);",
  1453. operand_size, operand_size);
  1454. break;
  1455. case '(':
  1456. if (strncmp (operands, "x)", 2) == 0)
  1457. {
  1458. if (addr_set == 0)
  1459. {
  1460. current_insn_size += 1;
  1461. print (fp, col, "addr = cpu_get_x (cpu) + cpu_fetch8 (cpu);");
  1462. }
  1463. print (fp, col, "memory_write%s (cpu, addr, dst%s);",
  1464. operand_size, operand_size);
  1465. operands += 2;
  1466. result_size = operand_size;
  1467. }
  1468. else if (strncmp (operands, "y)", 2) == 0)
  1469. {
  1470. if (addr_set == 0)
  1471. {
  1472. current_insn_size += 1;
  1473. print (fp, col, "addr = cpu_get_y (cpu) + cpu_fetch8 (cpu);");
  1474. }
  1475. print (fp, col, "memory_write%s (cpu, addr, dst%s);",
  1476. operand_size, operand_size);
  1477. operands += 2;
  1478. result_size = operand_size;
  1479. }
  1480. else if (strncmp (operands, ")", 1) == 0)
  1481. {
  1482. if (addr_set == 0)
  1483. {
  1484. current_insn_size += 2;
  1485. print (fp, col, "addr = cpu_fetch16 (cpu);");
  1486. }
  1487. print (fp, col, "memory_write%s (cpu, addr, dst%s);",
  1488. operand_size, operand_size);
  1489. operands++;
  1490. result_size = operand_size;
  1491. }
  1492. else if (strncmp (operands, "sp)", 3) == 0)
  1493. {
  1494. print (fp, col, "cpu_%s_push_uint%s (cpu, dst%s);",
  1495. cpu_type == cpu6811 ? "m68hc11" : "m68hc12",
  1496. operand_size, operand_size);
  1497. operands += 3;
  1498. result_size = operand_size;
  1499. }
  1500. else
  1501. {
  1502. fatal_error (opcode, "Invalid operand");
  1503. }
  1504. break;
  1505. case '[':
  1506. if (strncmp (operands, "]", 1) == 0)
  1507. {
  1508. if (addr_set == 0)
  1509. {
  1510. current_insn_size += 1;
  1511. print (fp, col, "addr = cpu_get_indexed_operand_addr (cpu,0);");
  1512. }
  1513. print (fp, col, "memory_write%s (cpu, addr, dst%s);",
  1514. operand_size, operand_size);
  1515. operands++;
  1516. result_size = operand_size;
  1517. }
  1518. else
  1519. {
  1520. fatal_error (opcode, "Invalid operand");
  1521. }
  1522. break;
  1523. case '{':
  1524. if (strncmp (operands, "}", 1) == 0)
  1525. {
  1526. current_insn_size += 1;
  1527. print (fp, col, "addr = cpu_get_indexed_operand_addr (cpu, 1);");
  1528. print (fp, col, "memory_write%s (cpu, addr, dst%s);",
  1529. operand_size, operand_size);
  1530. operands++;
  1531. result_size = operand_size;
  1532. }
  1533. else
  1534. {
  1535. fatal_error (opcode, "Invalid operand");
  1536. }
  1537. break;
  1538. case 's':
  1539. if (strncmp (operands, "p", 1) == 0)
  1540. {
  1541. print (fp, col, "cpu_set_sp (cpu, dst16);");
  1542. operands++;
  1543. result_size = "16";
  1544. }
  1545. else
  1546. {
  1547. fatal_error (opcode, "Invalid operand");
  1548. }
  1549. break;
  1550. case 'c':
  1551. if (strncmp (operands, "cr", 2) == 0)
  1552. {
  1553. print (fp, col, "cpu_set_ccr (cpu, dst8);");
  1554. operands += 2;
  1555. result_size = "8";
  1556. }
  1557. else
  1558. {
  1559. fatal_error (opcode, "Invalid operand");
  1560. }
  1561. break;
  1562. default:
  1563. fatal_error (opcode, "Invalid operand");
  1564. break;
  1565. }
  1566. if (*operands != 0)
  1567. fatal_error (opcode, "Garbage at end of operand");
  1568. if (result_size == 0)
  1569. fatal_error (opcode, "? No result seems to be saved");
  1570. if (strcmp (result_size, operand_size) != 0)
  1571. fatal_error (opcode, "Result saved different than pattern size");
  1572. }
  1573. /* Find the instruction pattern for a given instruction. */
  1574. const struct m6811_opcode_pattern*
  1575. find_opcode_pattern (const struct m6811_opcode_def *opcode)
  1576. {
  1577. int i;
  1578. const char *pattern = opcode->insn_pattern;
  1579. if (pattern == 0)
  1580. {
  1581. pattern = opcode->name;
  1582. }
  1583. for (i = 0; i < ARRAY_SIZE (m6811_opcode_patterns); i++)
  1584. {
  1585. if (strcmp (m6811_opcode_patterns[i].name, pattern) == 0)
  1586. {
  1587. return &m6811_opcode_patterns[i];
  1588. }
  1589. }
  1590. fatal_error (opcode, "Unknown instruction pattern");
  1591. return 0;
  1592. }
  1593. /* Generate the code for interpretation of instruction 'opcode'. */
  1594. void
  1595. gen_interp (FILE *fp, int col, const struct m6811_opcode_def *opcode)
  1596. {
  1597. const char *operands = opcode->operands;
  1598. int addr_set;
  1599. const char *pattern = opcode->insn_pattern;
  1600. const struct m6811_opcode_pattern *op;
  1601. const char *operand_size;
  1602. if (pattern == 0)
  1603. {
  1604. pattern = opcode->name;
  1605. }
  1606. /* Find out the size of the operands: 8 or 16-bits. */
  1607. if (strcmp(&pattern[strlen(pattern) - 1], "8") == 0)
  1608. {
  1609. operand_size = "8";
  1610. }
  1611. else if (strcmp (&pattern[strlen(pattern) - 2], "16") == 0)
  1612. {
  1613. operand_size = "16";
  1614. }
  1615. else
  1616. {
  1617. operand_size = "";
  1618. }
  1619. if (operands == 0)
  1620. operands = "";
  1621. /* Generate entry point for the instruction. */
  1622. print (fp, col, "case 0x%02x: /* %s %s */\n", opcode->insn_code,
  1623. opcode->name, operands);
  1624. col += indent_level;
  1625. /* Generate the code to get the instruction operands. */
  1626. addr_set = gen_fetch_operands (fp, col, opcode, operand_size);
  1627. /* Generate instruction interpretation. */
  1628. op = find_opcode_pattern (opcode);
  1629. if (op->pattern)
  1630. {
  1631. print (fp, col, "%s;", op->pattern);
  1632. }
  1633. /* Generate the code to save the result. */
  1634. gen_save_result (fp, col, opcode, addr_set, operand_size);
  1635. /* For some instructions, generate the code to update the flags. */
  1636. if (op && op->ccr_update)
  1637. {
  1638. print (fp, col, "%s;", op->ccr_update);
  1639. }
  1640. print (fp, col, "break;");
  1641. }
  1642. /* Generate the interpretor for a given 68HC11 page set. */
  1643. void
  1644. gen_interpreter_for_table (FILE *fp, int col,
  1645. const struct m6811_opcode_def *table,
  1646. int size,
  1647. const char *cycles_table_name)
  1648. {
  1649. int i;
  1650. int init_size;
  1651. init_size = table == m6811_page1_opcodes
  1652. || table == m6812_page1_opcodes? 1 : 2;
  1653. /* Get the opcode and dispatch directly. */
  1654. print (fp, col, "op = cpu_fetch8 (cpu);");
  1655. print (fp, col, "cpu_add_cycles (cpu, %s[op]);", cycles_table_name);
  1656. print (fp, col, "switch (op)\n");
  1657. col += indent_level;
  1658. print (fp, col, "{\n");
  1659. for (i = 0; i < size; i++)
  1660. {
  1661. /* The table contains duplicate entries (ie, instruction aliases). */
  1662. if (i > 0 && table[i].insn_code == table[i - 1].insn_code)
  1663. continue;
  1664. current_insn_size = init_size;
  1665. gen_interp (fp, col, &table[i]);
  1666. #if 0
  1667. if (current_insn_size != table[i].insn_size)
  1668. {
  1669. fatal_error (&table[i], "Insn size %ld inconsistent with %ld",
  1670. current_insn_size, table[i].insn_size);
  1671. }
  1672. #endif
  1673. }
  1674. print (fp, col, "default:\n");
  1675. print (fp, col + indent_level, "cpu_special (cpu, M6811_ILLEGAL);");
  1676. print (fp, col + indent_level, "break;");
  1677. print (fp, col, "}\n");
  1678. }
  1679. /* Generate the table of instruction cycle. These tables are indexed
  1680. by the opcode number to allow a fast cycle time computation. */
  1681. void
  1682. gen_cycle_table (FILE *fp, const char *name,
  1683. const struct m6811_opcode_def *table,
  1684. int size)
  1685. {
  1686. int i;
  1687. char cycles[256];
  1688. int page1;
  1689. page1 = table == m6811_page1_opcodes;
  1690. /* Build the cycles table. The table is indexed by the opcode. */
  1691. memset (cycles, 0, sizeof (cycles));
  1692. while (--size >= 0)
  1693. {
  1694. if (table->insn_min_cycles > table->insn_max_cycles)
  1695. fatal_error (table, "Wrong insn cycles");
  1696. if (table->insn_max_cycles == _M)
  1697. cycles[table->insn_code] = table->insn_min_cycles;
  1698. else
  1699. cycles[table->insn_code] = table->insn_max_cycles;
  1700. table++;
  1701. }
  1702. /* Some check: for the page1 opcode, the cycle type of the page2/3/4
  1703. opcode must be 0. */
  1704. if (page1 && (cycles[M6811_OPCODE_PAGE2] != 0
  1705. || cycles[M6811_OPCODE_PAGE3] != 0
  1706. || cycles[M6811_OPCODE_PAGE4] != 0))
  1707. fatal_error (0, "Invalid cycle table");
  1708. /* Generates the cycles table. */
  1709. print (fp, 0, "static const unsigned char %s[256] = {\n", name);
  1710. for (i = 0; i < 256; i++)
  1711. {
  1712. if ((i % 16) == 0)
  1713. {
  1714. print (fp, indent_level, "/* %3d */ ", i);
  1715. }
  1716. fprintf (fp, "%2d", cycles[i]);
  1717. if (i != 255)
  1718. fprintf (fp, ",");
  1719. if ((i % 16) != 15)
  1720. fprintf (fp, " ");
  1721. else
  1722. fprintf (fp, "\n");
  1723. }
  1724. print (fp, 0, "};\n\n");
  1725. }
  1726. #define USE_SRC8 1
  1727. #define USE_DST8 2
  1728. void
  1729. gen_function_entry (FILE *fp, const char *name, int locals)
  1730. {
  1731. /* Generate interpretor entry point. */
  1732. print (fp, 0, "%s (sim_cpu *cpu)\n", name);
  1733. print (fp, indent_level, "{\n");
  1734. /* Interpretor local variables. */
  1735. print (fp, indent_level, "unsigned char op;");
  1736. print (fp, indent_level, "uint16_t addr, src16, dst16;");
  1737. if (locals & USE_SRC8)
  1738. print (fp, indent_level, "uint8_t src8;\n");
  1739. if (locals & USE_DST8)
  1740. print (fp, indent_level, "uint8_t dst8;\n");
  1741. }
  1742. void
  1743. gen_function_close (FILE *fp)
  1744. {
  1745. print (fp, 0, "}\n");
  1746. }
  1747. int
  1748. cmp_opcode (const void *e1, const void *e2)
  1749. {
  1750. struct m6811_opcode_def* op1 = (struct m6811_opcode_def*) e1;
  1751. struct m6811_opcode_def* op2 = (struct m6811_opcode_def*) e2;
  1752. return (int) (op1->insn_code) - (int) (op2->insn_code);
  1753. }
  1754. void
  1755. prepare_table (struct m6811_opcode_def* table, int size)
  1756. {
  1757. int i;
  1758. qsort (table, size, sizeof (table[0]), cmp_opcode);
  1759. for (i = 1; i < size; i++)
  1760. {
  1761. if (table[i].insn_code == table[i-1].insn_code)
  1762. {
  1763. fprintf (stderr, "Two insns with code 0x%02x\n",
  1764. table[i].insn_code);
  1765. }
  1766. }
  1767. }
  1768. void
  1769. gen_interpreter (FILE *fp)
  1770. {
  1771. int col = 0;
  1772. prepare_table (m6811_page1_opcodes, ARRAY_SIZE (m6811_page1_opcodes));
  1773. prepare_table (m6811_page2_opcodes, ARRAY_SIZE (m6811_page2_opcodes));
  1774. prepare_table (m6811_page3_opcodes, ARRAY_SIZE (m6811_page3_opcodes));
  1775. prepare_table (m6811_page4_opcodes, ARRAY_SIZE (m6811_page4_opcodes));
  1776. prepare_table (m6812_page1_opcodes, ARRAY_SIZE (m6812_page1_opcodes));
  1777. prepare_table (m6812_page2_opcodes, ARRAY_SIZE (m6812_page2_opcodes));
  1778. /* Generate header of interpretor. */
  1779. print (fp, col, "/* File generated automatically by gencode. */\n");
  1780. print (fp, col, "#include \"sim-main.h\"\n\n");
  1781. if (cpu_type & cpu6811)
  1782. {
  1783. gen_cycle_table (fp, "cycles_page1", m6811_page1_opcodes,
  1784. ARRAY_SIZE (m6811_page1_opcodes));
  1785. gen_cycle_table (fp, "cycles_page2", m6811_page2_opcodes,
  1786. ARRAY_SIZE (m6811_page2_opcodes));
  1787. gen_cycle_table (fp, "cycles_page3", m6811_page3_opcodes,
  1788. ARRAY_SIZE (m6811_page3_opcodes));
  1789. gen_cycle_table (fp, "cycles_page4", m6811_page4_opcodes,
  1790. ARRAY_SIZE (m6811_page4_opcodes));
  1791. gen_function_entry (fp, "static void\ncpu_page3_interp", 0);
  1792. gen_interpreter_for_table (fp, indent_level,
  1793. m6811_page3_opcodes,
  1794. ARRAY_SIZE (m6811_page3_opcodes),
  1795. "cycles_page3");
  1796. gen_function_close (fp);
  1797. gen_function_entry (fp, "static void\ncpu_page4_interp", 0);
  1798. gen_interpreter_for_table (fp, indent_level,
  1799. m6811_page4_opcodes,
  1800. ARRAY_SIZE (m6811_page4_opcodes),
  1801. "cycles_page4");
  1802. gen_function_close (fp);
  1803. /* Generate the page 2, 3 and 4 handlers. */
  1804. gen_function_entry (fp, "static void\ncpu_page2_interp",
  1805. USE_SRC8 | USE_DST8);
  1806. gen_interpreter_for_table (fp, indent_level,
  1807. m6811_page2_opcodes,
  1808. ARRAY_SIZE (m6811_page2_opcodes),
  1809. "cycles_page2");
  1810. gen_function_close (fp);
  1811. /* Generate the interpretor entry point. */
  1812. gen_function_entry (fp, "void\ncpu_interp_m6811",
  1813. USE_SRC8 | USE_DST8);
  1814. gen_interpreter_for_table (fp, indent_level, m6811_page1_opcodes,
  1815. ARRAY_SIZE (m6811_page1_opcodes),
  1816. "cycles_page1");
  1817. gen_function_close (fp);
  1818. }
  1819. else
  1820. {
  1821. gen_cycle_table (fp, "cycles_page1", m6812_page1_opcodes,
  1822. ARRAY_SIZE (m6812_page1_opcodes));
  1823. gen_cycle_table (fp, "cycles_page2", m6812_page2_opcodes,
  1824. ARRAY_SIZE (m6812_page2_opcodes));
  1825. gen_function_entry (fp, "static void\ncpu_page2_interp",
  1826. USE_SRC8 | USE_DST8);
  1827. gen_interpreter_for_table (fp, indent_level,
  1828. m6812_page2_opcodes,
  1829. ARRAY_SIZE (m6812_page2_opcodes),
  1830. "cycles_page2");
  1831. gen_function_close (fp);
  1832. /* Generate the interpretor entry point. */
  1833. gen_function_entry (fp, "void\ncpu_interp_m6812",
  1834. USE_SRC8 | USE_DST8);
  1835. gen_interpreter_for_table (fp, indent_level, m6812_page1_opcodes,
  1836. ARRAY_SIZE (m6812_page1_opcodes),
  1837. "cycles_page1");
  1838. gen_function_close (fp);
  1839. }
  1840. }
  1841. void
  1842. usage (char* prog)
  1843. {
  1844. fprintf (stderr, "Usage: %s {-m6811|-m6812}\n", prog);
  1845. exit (2);
  1846. }
  1847. int
  1848. main (int argc, char *argv[])
  1849. {
  1850. int i;
  1851. for (i = 1; i < argc; i++)
  1852. {
  1853. if (strcmp (argv[i], "-m6811") == 0)
  1854. cpu_type = cpu6811;
  1855. else if (strcmp (argv[i], "-m6812") == 0)
  1856. cpu_type = cpu6812;
  1857. else
  1858. {
  1859. usage (argv[0]);
  1860. }
  1861. }
  1862. if (cpu_type == 0)
  1863. usage (argv[0]);
  1864. gen_interpreter (stdout);
  1865. if (fclose (stdout) != 0)
  1866. {
  1867. fprintf (stderr, "Error while generating the interpreter: %d\n",
  1868. errno);
  1869. return 1;
  1870. }
  1871. return 0;
  1872. }