rx.c 46 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282
  1. /* rx.c --- opcode semantics for stand-alone RX simulator.
  2. Copyright (C) 2008-2022 Free Software Foundation, Inc.
  3. Contributed by Red Hat, Inc.
  4. This file is part of the GNU simulators.
  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 <signal.h>
  21. #include "libiberty.h"
  22. #include "opcode/rx.h"
  23. #include "cpu.h"
  24. #include "mem.h"
  25. #include "syscalls.h"
  26. #include "fpu.h"
  27. #include "err.h"
  28. #include "misc.h"
  29. #ifdef WITH_PROFILE
  30. static const char * id_names[] = {
  31. "RXO_unknown",
  32. "RXO_mov", /* d = s (signed) */
  33. "RXO_movbi", /* d = [s,s2] (signed) */
  34. "RXO_movbir", /* [s,s2] = d (signed) */
  35. "RXO_pushm", /* s..s2 */
  36. "RXO_popm", /* s..s2 */
  37. "RXO_xchg", /* s <-> d */
  38. "RXO_stcc", /* d = s if cond(s2) */
  39. "RXO_rtsd", /* rtsd, 1=imm, 2-0 = reg if reg type */
  40. /* These are all either d OP= s or, if s2 is set, d = s OP s2. Note
  41. that d may be "None". */
  42. "RXO_and",
  43. "RXO_or",
  44. "RXO_xor",
  45. "RXO_add",
  46. "RXO_sub",
  47. "RXO_mul",
  48. "RXO_div",
  49. "RXO_divu",
  50. "RXO_shll",
  51. "RXO_shar",
  52. "RXO_shlr",
  53. "RXO_adc", /* d = d + s + carry */
  54. "RXO_sbb", /* d = d - s - ~carry */
  55. "RXO_abs", /* d = |s| */
  56. "RXO_max", /* d = max(d,s) */
  57. "RXO_min", /* d = min(d,s) */
  58. "RXO_emul", /* d:64 = d:32 * s */
  59. "RXO_emulu", /* d:64 = d:32 * s (unsigned) */
  60. "RXO_rolc", /* d <<= 1 through carry */
  61. "RXO_rorc", /* d >>= 1 through carry*/
  62. "RXO_rotl", /* d <<= #s without carry */
  63. "RXO_rotr", /* d >>= #s without carry*/
  64. "RXO_revw", /* d = revw(s) */
  65. "RXO_revl", /* d = revl(s) */
  66. "RXO_branch", /* pc = d if cond(s) */
  67. "RXO_branchrel",/* pc += d if cond(s) */
  68. "RXO_jsr", /* pc = d */
  69. "RXO_jsrrel", /* pc += d */
  70. "RXO_rts",
  71. "RXO_nop",
  72. "RXO_nop2",
  73. "RXO_nop3",
  74. "RXO_nop4",
  75. "RXO_nop5",
  76. "RXO_nop6",
  77. "RXO_nop7",
  78. "RXO_scmpu",
  79. "RXO_smovu",
  80. "RXO_smovb",
  81. "RXO_suntil",
  82. "RXO_swhile",
  83. "RXO_smovf",
  84. "RXO_sstr",
  85. "RXO_rmpa",
  86. "RXO_mulhi",
  87. "RXO_mullo",
  88. "RXO_machi",
  89. "RXO_maclo",
  90. "RXO_mvtachi",
  91. "RXO_mvtaclo",
  92. "RXO_mvfachi",
  93. "RXO_mvfacmi",
  94. "RXO_mvfaclo",
  95. "RXO_racw",
  96. "RXO_sat", /* sat(d) */
  97. "RXO_satr",
  98. "RXO_fadd", /* d op= s */
  99. "RXO_fcmp",
  100. "RXO_fsub",
  101. "RXO_ftoi",
  102. "RXO_fmul",
  103. "RXO_fdiv",
  104. "RXO_round",
  105. "RXO_itof",
  106. "RXO_bset", /* d |= (1<<s) */
  107. "RXO_bclr", /* d &= ~(1<<s) */
  108. "RXO_btst", /* s & (1<<s2) */
  109. "RXO_bnot", /* d ^= (1<<s) */
  110. "RXO_bmcc", /* d<s> = cond(s2) */
  111. "RXO_clrpsw", /* flag index in d */
  112. "RXO_setpsw", /* flag index in d */
  113. "RXO_mvtipl", /* new IPL in s */
  114. "RXO_rtfi",
  115. "RXO_rte",
  116. "RXO_rtd", /* undocumented */
  117. "RXO_brk",
  118. "RXO_dbt", /* undocumented */
  119. "RXO_int", /* vector id in s */
  120. "RXO_stop",
  121. "RXO_wait",
  122. "RXO_sccnd", /* d = cond(s) ? 1 : 0 */
  123. };
  124. static const char * optype_names[] = {
  125. " - ",
  126. "#Imm", /* #addend */
  127. " Rn ", /* Rn */
  128. "[Rn]", /* [Rn + addend] */
  129. "Ps++", /* [Rn+] */
  130. "--Pr", /* [-Rn] */
  131. " cc ", /* eq, gtu, etc */
  132. "Flag", /* [UIOSZC] */
  133. "RbRi" /* [Rb + scale * Ri] */
  134. };
  135. #define N_RXO ARRAY_SIZE (id_names)
  136. #define N_RXT ARRAY_SIZE (optype_names)
  137. #define N_MAP 90
  138. static unsigned long long benchmark_start_cycle;
  139. static unsigned long long benchmark_end_cycle;
  140. static int op_cache[N_RXT][N_RXT][N_RXT];
  141. static int op_cache_rev[N_MAP];
  142. static int op_cache_idx = 0;
  143. static int
  144. op_lookup (int a, int b, int c)
  145. {
  146. if (op_cache[a][b][c])
  147. return op_cache[a][b][c];
  148. op_cache_idx ++;
  149. if (op_cache_idx >= N_MAP)
  150. {
  151. printf("op_cache_idx exceeds %d\n", N_MAP);
  152. exit(1);
  153. }
  154. op_cache[a][b][c] = op_cache_idx;
  155. op_cache_rev[op_cache_idx] = (a<<8) | (b<<4) | c;
  156. return op_cache_idx;
  157. }
  158. static char *
  159. op_cache_string (int map)
  160. {
  161. static int ci;
  162. static char cb[5][20];
  163. int a, b, c;
  164. map = op_cache_rev[map];
  165. a = (map >> 8) & 15;
  166. b = (map >> 4) & 15;
  167. c = (map >> 0) & 15;
  168. ci = (ci + 1) % 5;
  169. sprintf(cb[ci], "%s %s %s", optype_names[a], optype_names[b], optype_names[c]);
  170. return cb[ci];
  171. }
  172. static unsigned long long cycles_per_id[N_RXO][N_MAP];
  173. static unsigned long long times_per_id[N_RXO][N_MAP];
  174. static unsigned long long memory_stalls;
  175. static unsigned long long register_stalls;
  176. static unsigned long long branch_stalls;
  177. static unsigned long long branch_alignment_stalls;
  178. static unsigned long long fast_returns;
  179. static unsigned long times_per_pair[N_RXO][N_MAP][N_RXO][N_MAP];
  180. static int prev_opcode_id = RXO_unknown;
  181. static int po0;
  182. #define STATS(x) x
  183. #else
  184. #define STATS(x)
  185. #endif /* WITH_PROFILE */
  186. #ifdef CYCLE_ACCURATE
  187. static int new_rt = -1;
  188. /* Number of cycles to add if an insn spans an 8-byte boundary. */
  189. static int branch_alignment_penalty = 0;
  190. #endif
  191. static int running_benchmark = 1;
  192. #define tprintf if (trace && running_benchmark) printf
  193. jmp_buf decode_jmp_buf;
  194. unsigned int rx_cycles = 0;
  195. #ifdef CYCLE_ACCURATE
  196. /* If nonzero, memory was read at some point and cycle latency might
  197. take effect. */
  198. static int memory_source = 0;
  199. /* If nonzero, memory was written and extra cycles might be
  200. needed. */
  201. static int memory_dest = 0;
  202. static void
  203. cycles (int throughput)
  204. {
  205. tprintf("%d cycles\n", throughput);
  206. regs.cycle_count += throughput;
  207. }
  208. /* Number of execution (E) cycles the op uses. For memory sources, we
  209. include the load micro-op stall as two extra E cycles. */
  210. #define E(c) cycles (memory_source ? c + 2 : c)
  211. #define E1 cycles (1)
  212. #define E2 cycles (2)
  213. #define EBIT cycles (memory_source ? 2 : 1)
  214. /* Check to see if a read latency must be applied for a given register. */
  215. #define RL(r) \
  216. if (regs.rt == r ) \
  217. { \
  218. tprintf("register %d load stall\n", r); \
  219. regs.cycle_count ++; \
  220. STATS(register_stalls ++); \
  221. regs.rt = -1; \
  222. }
  223. #define RLD(r) \
  224. if (memory_source) \
  225. { \
  226. tprintf ("Rt now %d\n", r); \
  227. new_rt = r; \
  228. }
  229. static int
  230. lsb_count (unsigned long v, int is_signed)
  231. {
  232. int i, lsb;
  233. if (is_signed && (v & 0x80000000U))
  234. v = (unsigned long)(long)(-v);
  235. for (i=31; i>=0; i--)
  236. if (v & (1 << i))
  237. {
  238. /* v is 0..31, we want 1=1-2, 2=3-4, 3=5-6, etc. */
  239. lsb = (i + 2) / 2;
  240. return lsb;
  241. }
  242. return 0;
  243. }
  244. static int
  245. divu_cycles(unsigned long num, unsigned long den)
  246. {
  247. int nb = lsb_count (num, 0);
  248. int db = lsb_count (den, 0);
  249. int rv;
  250. if (nb < db)
  251. rv = 2;
  252. else
  253. rv = 3 + nb - db;
  254. E (rv);
  255. return rv;
  256. }
  257. static int
  258. div_cycles(long num, long den)
  259. {
  260. int nb = lsb_count ((unsigned long)num, 1);
  261. int db = lsb_count ((unsigned long)den, 1);
  262. int rv;
  263. if (nb < db)
  264. rv = 3;
  265. else
  266. rv = 5 + nb - db;
  267. E (rv);
  268. return rv;
  269. }
  270. #else /* !CYCLE_ACCURATE */
  271. #define cycles(t)
  272. #define E(c)
  273. #define E1
  274. #define E2
  275. #define EBIT
  276. #define RL(r)
  277. #define RLD(r)
  278. #define divu_cycles(n,d)
  279. #define div_cycles(n,d)
  280. #endif /* else CYCLE_ACCURATE */
  281. static int size2bytes[] = {
  282. 4, 1, 1, 1, 2, 2, 2, 3, 4
  283. };
  284. typedef struct {
  285. unsigned long dpc;
  286. } RX_Data;
  287. #define rx_abort() _rx_abort(__FILE__, __LINE__)
  288. static void
  289. _rx_abort (const char *file, int line)
  290. {
  291. if (strrchr (file, '/'))
  292. file = strrchr (file, '/') + 1;
  293. fprintf(stderr, "abort at %s:%d\n", file, line);
  294. abort();
  295. }
  296. static unsigned char *get_byte_base;
  297. static RX_Opcode_Decoded **decode_cache_base;
  298. static SI get_byte_page;
  299. void
  300. reset_decoder (void)
  301. {
  302. get_byte_base = 0;
  303. decode_cache_base = 0;
  304. get_byte_page = 0;
  305. }
  306. static inline void
  307. maybe_get_mem_page (SI tpc)
  308. {
  309. if (((tpc ^ get_byte_page) & NONPAGE_MASK) || enable_counting)
  310. {
  311. get_byte_page = tpc & NONPAGE_MASK;
  312. get_byte_base = rx_mem_ptr (get_byte_page, MPA_READING) - get_byte_page;
  313. decode_cache_base = rx_mem_decode_cache (get_byte_page) - get_byte_page;
  314. }
  315. }
  316. /* This gets called a *lot* so optimize it. */
  317. static int
  318. rx_get_byte (void *vdata)
  319. {
  320. RX_Data *rx_data = (RX_Data *)vdata;
  321. SI tpc = rx_data->dpc;
  322. /* See load.c for an explanation of this. */
  323. if (rx_big_endian)
  324. tpc ^= 3;
  325. maybe_get_mem_page (tpc);
  326. rx_data->dpc ++;
  327. return get_byte_base [tpc];
  328. }
  329. static int
  330. get_op (const RX_Opcode_Decoded *rd, int i)
  331. {
  332. const RX_Opcode_Operand *o = rd->op + i;
  333. int addr, rv = 0;
  334. switch (o->type)
  335. {
  336. case RX_Operand_None:
  337. rx_abort ();
  338. case RX_Operand_Immediate: /* #addend */
  339. return o->addend;
  340. case RX_Operand_Register: /* Rn */
  341. RL (o->reg);
  342. rv = get_reg (o->reg);
  343. break;
  344. case RX_Operand_Predec: /* [-Rn] */
  345. put_reg (o->reg, get_reg (o->reg) - size2bytes[o->size]);
  346. /* fall through */
  347. case RX_Operand_Postinc: /* [Rn+] */
  348. case RX_Operand_Zero_Indirect: /* [Rn + 0] */
  349. case RX_Operand_Indirect: /* [Rn + addend] */
  350. case RX_Operand_TwoReg: /* [Rn + scale * R2] */
  351. #ifdef CYCLE_ACCURATE
  352. RL (o->reg);
  353. if (o->type == RX_Operand_TwoReg)
  354. RL (rd->op[2].reg);
  355. regs.rt = -1;
  356. if (regs.m2m == M2M_BOTH)
  357. {
  358. tprintf("src memory stall\n");
  359. #ifdef WITH_PROFILE
  360. memory_stalls ++;
  361. #endif
  362. regs.cycle_count ++;
  363. regs.m2m = 0;
  364. }
  365. memory_source = 1;
  366. #endif
  367. if (o->type == RX_Operand_TwoReg)
  368. addr = get_reg (o->reg) * size2bytes[rd->size] + get_reg (rd->op[2].reg);
  369. else
  370. addr = get_reg (o->reg) + o->addend;
  371. switch (o->size)
  372. {
  373. default:
  374. case RX_AnySize:
  375. rx_abort ();
  376. case RX_Byte: /* undefined extension */
  377. case RX_UByte:
  378. case RX_SByte:
  379. rv = mem_get_qi (addr);
  380. break;
  381. case RX_Word: /* undefined extension */
  382. case RX_UWord:
  383. case RX_SWord:
  384. rv = mem_get_hi (addr);
  385. break;
  386. case RX_3Byte:
  387. rv = mem_get_psi (addr);
  388. break;
  389. case RX_Long:
  390. rv = mem_get_si (addr);
  391. break;
  392. }
  393. if (o->type == RX_Operand_Postinc)
  394. put_reg (o->reg, get_reg (o->reg) + size2bytes[o->size]);
  395. break;
  396. case RX_Operand_Condition: /* eq, gtu, etc */
  397. return condition_true (o->reg);
  398. case RX_Operand_Flag: /* [UIOSZC] */
  399. return (regs.r_psw & (1 << o->reg)) ? 1 : 0;
  400. }
  401. /* if we've gotten here, we need to clip/extend the value according
  402. to the size. */
  403. switch (o->size)
  404. {
  405. default:
  406. case RX_AnySize:
  407. rx_abort ();
  408. case RX_Byte: /* undefined extension */
  409. rv |= 0xdeadbe00; /* keep them honest */
  410. break;
  411. case RX_UByte:
  412. rv &= 0xff;
  413. break;
  414. case RX_SByte:
  415. rv = sign_ext (rv, 8);
  416. break;
  417. case RX_Word: /* undefined extension */
  418. rv |= 0xdead0000; /* keep them honest */
  419. break;
  420. case RX_UWord:
  421. rv &= 0xffff;
  422. break;
  423. case RX_SWord:
  424. rv = sign_ext (rv, 16);
  425. break;
  426. case RX_3Byte:
  427. rv &= 0xffffff;
  428. break;
  429. case RX_Long:
  430. break;
  431. }
  432. return rv;
  433. }
  434. static void
  435. put_op (const RX_Opcode_Decoded *rd, int i, int v)
  436. {
  437. const RX_Opcode_Operand *o = rd->op + i;
  438. int addr;
  439. switch (o->size)
  440. {
  441. default:
  442. case RX_AnySize:
  443. if (o->type != RX_Operand_Register)
  444. rx_abort ();
  445. break;
  446. case RX_Byte: /* undefined extension */
  447. v |= 0xdeadbe00; /* keep them honest */
  448. break;
  449. case RX_UByte:
  450. v &= 0xff;
  451. break;
  452. case RX_SByte:
  453. v = sign_ext (v, 8);
  454. break;
  455. case RX_Word: /* undefined extension */
  456. v |= 0xdead0000; /* keep them honest */
  457. break;
  458. case RX_UWord:
  459. v &= 0xffff;
  460. break;
  461. case RX_SWord:
  462. v = sign_ext (v, 16);
  463. break;
  464. case RX_3Byte:
  465. v &= 0xffffff;
  466. break;
  467. case RX_Long:
  468. break;
  469. }
  470. switch (o->type)
  471. {
  472. case RX_Operand_None:
  473. /* Opcodes like TST and CMP use this. */
  474. break;
  475. case RX_Operand_Immediate: /* #addend */
  476. case RX_Operand_Condition: /* eq, gtu, etc */
  477. rx_abort ();
  478. case RX_Operand_Register: /* Rn */
  479. put_reg (o->reg, v);
  480. RLD (o->reg);
  481. break;
  482. case RX_Operand_Predec: /* [-Rn] */
  483. put_reg (o->reg, get_reg (o->reg) - size2bytes[o->size]);
  484. /* fall through */
  485. case RX_Operand_Postinc: /* [Rn+] */
  486. case RX_Operand_Zero_Indirect: /* [Rn + 0] */
  487. case RX_Operand_Indirect: /* [Rn + addend] */
  488. case RX_Operand_TwoReg: /* [Rn + scale * R2] */
  489. #ifdef CYCLE_ACCURATE
  490. if (regs.m2m == M2M_BOTH)
  491. {
  492. tprintf("dst memory stall\n");
  493. regs.cycle_count ++;
  494. #ifdef WITH_PROFILE
  495. memory_stalls ++;
  496. #endif
  497. regs.m2m = 0;
  498. }
  499. memory_dest = 1;
  500. #endif
  501. if (o->type == RX_Operand_TwoReg)
  502. addr = get_reg (o->reg) * size2bytes[rd->size] + get_reg (rd->op[2].reg);
  503. else
  504. addr = get_reg (o->reg) + o->addend;
  505. switch (o->size)
  506. {
  507. default:
  508. case RX_AnySize:
  509. rx_abort ();
  510. case RX_Byte: /* undefined extension */
  511. case RX_UByte:
  512. case RX_SByte:
  513. mem_put_qi (addr, v);
  514. break;
  515. case RX_Word: /* undefined extension */
  516. case RX_UWord:
  517. case RX_SWord:
  518. mem_put_hi (addr, v);
  519. break;
  520. case RX_3Byte:
  521. mem_put_psi (addr, v);
  522. break;
  523. case RX_Long:
  524. mem_put_si (addr, v);
  525. break;
  526. }
  527. if (o->type == RX_Operand_Postinc)
  528. put_reg (o->reg, get_reg (o->reg) + size2bytes[o->size]);
  529. break;
  530. case RX_Operand_Flag: /* [UIOSZC] */
  531. if (v)
  532. regs.r_psw |= (1 << o->reg);
  533. else
  534. regs.r_psw &= ~(1 << o->reg);
  535. break;
  536. }
  537. }
  538. #define PD(x) put_op (opcode, 0, x)
  539. #define PS(x) put_op (opcode, 1, x)
  540. #define PS2(x) put_op (opcode, 2, x)
  541. #define GD() get_op (opcode, 0)
  542. #define GS() get_op (opcode, 1)
  543. #define GS2() get_op (opcode, 2)
  544. #define DSZ() size2bytes[opcode->op[0].size]
  545. #define SSZ() size2bytes[opcode->op[0].size]
  546. #define S2SZ() size2bytes[opcode->op[0].size]
  547. /* "Universal" sources. */
  548. #define US1() ((opcode->op[2].type == RX_Operand_None) ? GD() : GS())
  549. #define US2() ((opcode->op[2].type == RX_Operand_None) ? GS() : GS2())
  550. static void
  551. push(int val)
  552. {
  553. int rsp = get_reg (sp);
  554. rsp -= 4;
  555. put_reg (sp, rsp);
  556. mem_put_si (rsp, val);
  557. }
  558. /* Just like the above, but tag the memory as "pushed pc" so if anyone
  559. tries to write to it, it will cause an error. */
  560. static void
  561. pushpc(int val)
  562. {
  563. int rsp = get_reg (sp);
  564. rsp -= 4;
  565. put_reg (sp, rsp);
  566. mem_put_si (rsp, val);
  567. mem_set_content_range (rsp, rsp+3, MC_PUSHED_PC);
  568. }
  569. static int
  570. pop (void)
  571. {
  572. int rv;
  573. int rsp = get_reg (sp);
  574. rv = mem_get_si (rsp);
  575. rsp += 4;
  576. put_reg (sp, rsp);
  577. return rv;
  578. }
  579. static int
  580. poppc (void)
  581. {
  582. int rv;
  583. int rsp = get_reg (sp);
  584. if (mem_get_content_type (rsp) != MC_PUSHED_PC)
  585. execution_error (SIM_ERR_CORRUPT_STACK, rsp);
  586. rv = mem_get_si (rsp);
  587. mem_set_content_range (rsp, rsp+3, MC_UNINIT);
  588. rsp += 4;
  589. put_reg (sp, rsp);
  590. return rv;
  591. }
  592. #define MATH_OP(vop,c) \
  593. { \
  594. umb = US2(); \
  595. uma = US1(); \
  596. ll = (unsigned long long) uma vop (unsigned long long) umb vop c; \
  597. tprintf ("0x%x " #vop " 0x%x " #vop " 0x%x = 0x%llx\n", uma, umb, c, ll); \
  598. ma = sign_ext (uma, DSZ() * 8); \
  599. mb = sign_ext (umb, DSZ() * 8); \
  600. sll = (long long) ma vop (long long) mb vop c; \
  601. tprintf ("%d " #vop " %d " #vop " %d = %lld\n", ma, mb, c, sll); \
  602. set_oszc (sll, DSZ(), (long long) ll > ((1 vop 1) ? (long long) b2mask[DSZ()] : (long long) -1)); \
  603. PD (sll); \
  604. E (1); \
  605. }
  606. #define LOGIC_OP(vop) \
  607. { \
  608. mb = US2(); \
  609. ma = US1(); \
  610. v = ma vop mb; \
  611. tprintf("0x%x " #vop " 0x%x = 0x%x\n", ma, mb, v); \
  612. set_sz (v, DSZ()); \
  613. PD(v); \
  614. E (1); \
  615. }
  616. #define SHIFT_OP(val, type, count, OP, carry_mask) \
  617. { \
  618. int i, c=0; \
  619. count = US2(); \
  620. val = (type)US1(); \
  621. tprintf("%lld " #OP " %d\n", val, count); \
  622. for (i = 0; i < count; i ++) \
  623. { \
  624. c = val & carry_mask; \
  625. val OP 1; \
  626. } \
  627. set_oszc (val, 4, c); \
  628. PD (val); \
  629. }
  630. typedef union {
  631. int i;
  632. float f;
  633. } FloatInt;
  634. static inline int
  635. float2int (float f)
  636. {
  637. FloatInt fi;
  638. fi.f = f;
  639. return fi.i;
  640. }
  641. static inline float
  642. int2float (int i)
  643. {
  644. FloatInt fi;
  645. fi.i = i;
  646. return fi.f;
  647. }
  648. static int
  649. fop_fadd (fp_t s1, fp_t s2, fp_t *d)
  650. {
  651. *d = rxfp_add (s1, s2);
  652. return 1;
  653. }
  654. static int
  655. fop_fmul (fp_t s1, fp_t s2, fp_t *d)
  656. {
  657. *d = rxfp_mul (s1, s2);
  658. return 1;
  659. }
  660. static int
  661. fop_fdiv (fp_t s1, fp_t s2, fp_t *d)
  662. {
  663. *d = rxfp_div (s1, s2);
  664. return 1;
  665. }
  666. static int
  667. fop_fsub (fp_t s1, fp_t s2, fp_t *d)
  668. {
  669. *d = rxfp_sub (s1, s2);
  670. return 1;
  671. }
  672. #define FPPENDING() (regs.r_fpsw & (FPSWBITS_CE | (FPSWBITS_FMASK & (regs.r_fpsw << FPSW_EFSH))))
  673. #define FPCLEAR() regs.r_fpsw &= FPSWBITS_CLEAR
  674. #define FPCHECK() \
  675. if (FPPENDING()) \
  676. return do_fp_exception (opcode_pc)
  677. #define FLOAT_OP(func) \
  678. { \
  679. int do_store; \
  680. fp_t fa, fb, fc; \
  681. FPCLEAR(); \
  682. fb = GS (); \
  683. fa = GD (); \
  684. do_store = fop_##func (fa, fb, &fc); \
  685. tprintf("%g " #func " %g = %g %08x\n", int2float(fa), int2float(fb), int2float(fc), fc); \
  686. FPCHECK(); \
  687. if (do_store) \
  688. PD (fc); \
  689. mb = 0; \
  690. if ((fc & 0x80000000UL) != 0) \
  691. mb |= FLAGBIT_S; \
  692. if ((fc & 0x7fffffffUL) == 0) \
  693. mb |= FLAGBIT_Z; \
  694. set_flags (FLAGBIT_S | FLAGBIT_Z, mb); \
  695. }
  696. #define carry (FLAG_C ? 1 : 0)
  697. static struct {
  698. unsigned long vaddr;
  699. const char *str;
  700. int signal;
  701. } exception_info[] = {
  702. { 0xFFFFFFD0UL, "priviledged opcode", SIGILL },
  703. { 0xFFFFFFD4UL, "access violation", SIGSEGV },
  704. { 0xFFFFFFDCUL, "undefined opcode", SIGILL },
  705. { 0xFFFFFFE4UL, "floating point", SIGFPE }
  706. };
  707. #define EX_PRIVILEDGED 0
  708. #define EX_ACCESS 1
  709. #define EX_UNDEFINED 2
  710. #define EX_FLOATING 3
  711. #define EXCEPTION(n) \
  712. return generate_exception (n, opcode_pc)
  713. #define PRIVILEDGED() \
  714. if (FLAG_PM) \
  715. EXCEPTION (EX_PRIVILEDGED)
  716. static int
  717. generate_exception (unsigned long type, SI opcode_pc)
  718. {
  719. SI old_psw, old_pc, new_pc;
  720. new_pc = mem_get_si (exception_info[type].vaddr);
  721. /* 0x00020000 is the value used to initialise the known
  722. exception vectors (see rx.ld), but it is a reserved
  723. area of memory so do not try to access it, and if the
  724. value has not been changed by the program then the
  725. vector has not been installed. */
  726. if (new_pc == 0 || new_pc == 0x00020000)
  727. {
  728. if (rx_in_gdb)
  729. return RX_MAKE_STOPPED (exception_info[type].signal);
  730. fprintf(stderr, "Unhandled %s exception at pc = %#lx\n",
  731. exception_info[type].str, (unsigned long) opcode_pc);
  732. if (type == EX_FLOATING)
  733. {
  734. int mask = FPPENDING ();
  735. fprintf (stderr, "Pending FP exceptions:");
  736. if (mask & FPSWBITS_FV)
  737. fprintf(stderr, " Invalid");
  738. if (mask & FPSWBITS_FO)
  739. fprintf(stderr, " Overflow");
  740. if (mask & FPSWBITS_FZ)
  741. fprintf(stderr, " Division-by-zero");
  742. if (mask & FPSWBITS_FU)
  743. fprintf(stderr, " Underflow");
  744. if (mask & FPSWBITS_FX)
  745. fprintf(stderr, " Inexact");
  746. if (mask & FPSWBITS_CE)
  747. fprintf(stderr, " Unimplemented");
  748. fprintf(stderr, "\n");
  749. }
  750. return RX_MAKE_EXITED (1);
  751. }
  752. tprintf ("Triggering %s exception\n", exception_info[type].str);
  753. old_psw = regs.r_psw;
  754. regs.r_psw &= ~ (FLAGBIT_I | FLAGBIT_U | FLAGBIT_PM);
  755. old_pc = opcode_pc;
  756. regs.r_pc = new_pc;
  757. pushpc (old_psw);
  758. pushpc (old_pc);
  759. return RX_MAKE_STEPPED ();
  760. }
  761. void
  762. generate_access_exception (void)
  763. {
  764. int rv;
  765. rv = generate_exception (EX_ACCESS, regs.r_pc);
  766. if (RX_EXITED (rv))
  767. longjmp (decode_jmp_buf, rv);
  768. }
  769. static int
  770. do_fp_exception (unsigned long opcode_pc)
  771. {
  772. while (FPPENDING())
  773. EXCEPTION (EX_FLOATING);
  774. return RX_MAKE_STEPPED ();
  775. }
  776. static int
  777. op_is_memory (const RX_Opcode_Decoded *rd, int i)
  778. {
  779. switch (rd->op[i].type)
  780. {
  781. case RX_Operand_Predec:
  782. case RX_Operand_Postinc:
  783. case RX_Operand_Indirect:
  784. return 1;
  785. default:
  786. return 0;
  787. }
  788. }
  789. #define OM(i) op_is_memory (opcode, i)
  790. #define DO_RETURN(x) { longjmp (decode_jmp_buf, x); }
  791. int
  792. decode_opcode (void)
  793. {
  794. unsigned int uma=0, umb=0;
  795. int ma=0, mb=0;
  796. int opcode_size, v;
  797. unsigned long long ll;
  798. long long sll;
  799. unsigned long opcode_pc;
  800. RX_Data rx_data;
  801. const RX_Opcode_Decoded *opcode;
  802. #ifdef WITH_PROFILE
  803. unsigned long long prev_cycle_count;
  804. #endif
  805. #ifdef CYCLE_ACCURATE
  806. unsigned int tx;
  807. #endif
  808. #ifdef WITH_PROFILE
  809. prev_cycle_count = regs.cycle_count;
  810. #endif
  811. #ifdef CYCLE_ACCURATE
  812. memory_source = 0;
  813. memory_dest = 0;
  814. #endif
  815. rx_cycles ++;
  816. maybe_get_mem_page (regs.r_pc);
  817. opcode_pc = regs.r_pc;
  818. /* Note that we don't word-swap this point, there's no point. */
  819. if (decode_cache_base[opcode_pc] == NULL)
  820. {
  821. RX_Opcode_Decoded *opcode_w;
  822. rx_data.dpc = opcode_pc;
  823. opcode_w = decode_cache_base[opcode_pc] = calloc (1, sizeof (RX_Opcode_Decoded));
  824. opcode_size = rx_decode_opcode (opcode_pc, opcode_w,
  825. rx_get_byte, &rx_data);
  826. opcode = opcode_w;
  827. }
  828. else
  829. {
  830. opcode = decode_cache_base[opcode_pc];
  831. opcode_size = opcode->n_bytes;
  832. }
  833. #ifdef CYCLE_ACCURATE
  834. if (branch_alignment_penalty)
  835. {
  836. if ((regs.r_pc ^ (regs.r_pc + opcode_size - 1)) & ~7)
  837. {
  838. tprintf("1 cycle branch alignment penalty\n");
  839. cycles (branch_alignment_penalty);
  840. #ifdef WITH_PROFILE
  841. branch_alignment_stalls ++;
  842. #endif
  843. }
  844. branch_alignment_penalty = 0;
  845. }
  846. #endif
  847. regs.r_pc += opcode_size;
  848. rx_flagmask = opcode->flags_s;
  849. rx_flagand = ~(int)opcode->flags_0;
  850. rx_flagor = opcode->flags_1;
  851. switch (opcode->id)
  852. {
  853. case RXO_abs:
  854. sll = GS ();
  855. tprintf("|%lld| = ", sll);
  856. if (sll < 0)
  857. sll = -sll;
  858. tprintf("%lld\n", sll);
  859. PD (sll);
  860. set_osz (sll, 4);
  861. E (1);
  862. break;
  863. case RXO_adc:
  864. MATH_OP (+,carry);
  865. break;
  866. case RXO_add:
  867. MATH_OP (+,0);
  868. break;
  869. case RXO_and:
  870. LOGIC_OP (&);
  871. break;
  872. case RXO_bclr:
  873. ma = GD ();
  874. mb = GS ();
  875. if (opcode->op[0].type == RX_Operand_Register)
  876. mb &= 0x1f;
  877. else
  878. mb &= 0x07;
  879. ma &= ~(1 << mb);
  880. PD (ma);
  881. EBIT;
  882. break;
  883. case RXO_bmcc:
  884. ma = GD ();
  885. mb = GS ();
  886. if (opcode->op[0].type == RX_Operand_Register)
  887. mb &= 0x1f;
  888. else
  889. mb &= 0x07;
  890. if (GS2 ())
  891. ma |= (1 << mb);
  892. else
  893. ma &= ~(1 << mb);
  894. PD (ma);
  895. EBIT;
  896. break;
  897. case RXO_bnot:
  898. ma = GD ();
  899. mb = GS ();
  900. if (opcode->op[0].type == RX_Operand_Register)
  901. mb &= 0x1f;
  902. else
  903. mb &= 0x07;
  904. ma ^= (1 << mb);
  905. PD (ma);
  906. EBIT;
  907. break;
  908. case RXO_branch:
  909. if (opcode->op[1].type == RX_Operand_None || GS())
  910. {
  911. #ifdef CYCLE_ACCURATE
  912. SI old_pc = regs.r_pc;
  913. int delta;
  914. #endif
  915. regs.r_pc = GD();
  916. #ifdef CYCLE_ACCURATE
  917. delta = regs.r_pc - old_pc;
  918. if (delta >= 0 && delta < 16
  919. && opcode_size > 1)
  920. {
  921. tprintf("near forward branch bonus\n");
  922. cycles (2);
  923. }
  924. else
  925. {
  926. cycles (3);
  927. branch_alignment_penalty = 1;
  928. }
  929. #ifdef WITH_PROFILE
  930. branch_stalls ++;
  931. #endif
  932. #endif
  933. }
  934. #ifdef CYCLE_ACCURATE
  935. else
  936. cycles (1);
  937. #endif
  938. break;
  939. case RXO_branchrel:
  940. if (opcode->op[1].type == RX_Operand_None || GS())
  941. {
  942. int delta = GD();
  943. regs.r_pc = opcode_pc + delta;
  944. #ifdef CYCLE_ACCURATE
  945. /* Note: specs say 3, chip says 2. */
  946. if (delta >= 0 && delta < 16
  947. && opcode_size > 1)
  948. {
  949. tprintf("near forward branch bonus\n");
  950. cycles (2);
  951. }
  952. else
  953. {
  954. cycles (3);
  955. branch_alignment_penalty = 1;
  956. }
  957. #ifdef WITH_PROFILE
  958. branch_stalls ++;
  959. #endif
  960. #endif
  961. }
  962. #ifdef CYCLE_ACCURATE
  963. else
  964. cycles (1);
  965. #endif
  966. break;
  967. case RXO_brk:
  968. {
  969. int old_psw = regs.r_psw;
  970. if (rx_in_gdb)
  971. DO_RETURN (RX_MAKE_HIT_BREAK ());
  972. if (regs.r_intb == 0)
  973. {
  974. tprintf("BREAK hit, no vector table.\n");
  975. DO_RETURN (RX_MAKE_EXITED(1));
  976. }
  977. regs.r_psw &= ~(FLAGBIT_I | FLAGBIT_U | FLAGBIT_PM);
  978. pushpc (old_psw);
  979. pushpc (regs.r_pc);
  980. regs.r_pc = mem_get_si (regs.r_intb);
  981. cycles(6);
  982. }
  983. break;
  984. case RXO_bset:
  985. ma = GD ();
  986. mb = GS ();
  987. if (opcode->op[0].type == RX_Operand_Register)
  988. mb &= 0x1f;
  989. else
  990. mb &= 0x07;
  991. ma |= (1 << mb);
  992. PD (ma);
  993. EBIT;
  994. break;
  995. case RXO_btst:
  996. ma = GS ();
  997. mb = GS2 ();
  998. if (opcode->op[1].type == RX_Operand_Register)
  999. mb &= 0x1f;
  1000. else
  1001. mb &= 0x07;
  1002. umb = ma & (1 << mb);
  1003. set_zc (! umb, umb);
  1004. EBIT;
  1005. break;
  1006. case RXO_clrpsw:
  1007. v = 1 << opcode->op[0].reg;
  1008. if (FLAG_PM
  1009. && (v == FLAGBIT_I
  1010. || v == FLAGBIT_U))
  1011. break;
  1012. regs.r_psw &= ~v;
  1013. cycles (1);
  1014. break;
  1015. case RXO_div: /* d = d / s */
  1016. ma = GS();
  1017. mb = GD();
  1018. tprintf("%d / %d = ", mb, ma);
  1019. if (ma == 0 || (ma == -1 && (unsigned int) mb == 0x80000000))
  1020. {
  1021. tprintf("#NAN\n");
  1022. set_flags (FLAGBIT_O, FLAGBIT_O);
  1023. cycles (3);
  1024. }
  1025. else
  1026. {
  1027. v = mb/ma;
  1028. tprintf("%d\n", v);
  1029. set_flags (FLAGBIT_O, 0);
  1030. PD (v);
  1031. div_cycles (mb, ma);
  1032. }
  1033. break;
  1034. case RXO_divu: /* d = d / s */
  1035. uma = GS();
  1036. umb = GD();
  1037. tprintf("%u / %u = ", umb, uma);
  1038. if (uma == 0)
  1039. {
  1040. tprintf("#NAN\n");
  1041. set_flags (FLAGBIT_O, FLAGBIT_O);
  1042. cycles (2);
  1043. }
  1044. else
  1045. {
  1046. v = umb / uma;
  1047. tprintf("%u\n", v);
  1048. set_flags (FLAGBIT_O, 0);
  1049. PD (v);
  1050. divu_cycles (umb, uma);
  1051. }
  1052. break;
  1053. case RXO_emul:
  1054. ma = GD ();
  1055. mb = GS ();
  1056. sll = (long long)ma * (long long)mb;
  1057. tprintf("%d * %d = %lld\n", ma, mb, sll);
  1058. put_reg (opcode->op[0].reg, sll);
  1059. put_reg (opcode->op[0].reg + 1, sll >> 32);
  1060. E2;
  1061. break;
  1062. case RXO_emulu:
  1063. uma = GD ();
  1064. umb = GS ();
  1065. ll = (long long)uma * (long long)umb;
  1066. tprintf("%#x * %#x = %#llx\n", uma, umb, ll);
  1067. put_reg (opcode->op[0].reg, ll);
  1068. put_reg (opcode->op[0].reg + 1, ll >> 32);
  1069. E2;
  1070. break;
  1071. case RXO_fadd:
  1072. FLOAT_OP (fadd);
  1073. E (4);
  1074. break;
  1075. case RXO_fcmp:
  1076. ma = GD();
  1077. mb = GS();
  1078. FPCLEAR ();
  1079. rxfp_cmp (ma, mb);
  1080. FPCHECK ();
  1081. E (1);
  1082. break;
  1083. case RXO_fdiv:
  1084. FLOAT_OP (fdiv);
  1085. E (16);
  1086. break;
  1087. case RXO_fmul:
  1088. FLOAT_OP (fmul);
  1089. E (3);
  1090. break;
  1091. case RXO_rtfi:
  1092. PRIVILEDGED ();
  1093. regs.r_psw = regs.r_bpsw;
  1094. regs.r_pc = regs.r_bpc;
  1095. #ifdef CYCLE_ACCURATE
  1096. regs.fast_return = 0;
  1097. cycles(3);
  1098. #endif
  1099. break;
  1100. case RXO_fsub:
  1101. FLOAT_OP (fsub);
  1102. E (4);
  1103. break;
  1104. case RXO_ftoi:
  1105. ma = GS ();
  1106. FPCLEAR ();
  1107. mb = rxfp_ftoi (ma, FPRM_ZERO);
  1108. FPCHECK ();
  1109. PD (mb);
  1110. tprintf("(int) %g = %d\n", int2float(ma), mb);
  1111. set_sz (mb, 4);
  1112. E (2);
  1113. break;
  1114. case RXO_int:
  1115. v = GS ();
  1116. if (v == 255)
  1117. {
  1118. int rc = rx_syscall (regs.r[5]);
  1119. if (! RX_STEPPED (rc))
  1120. DO_RETURN (rc);
  1121. }
  1122. else
  1123. {
  1124. int old_psw = regs.r_psw;
  1125. regs.r_psw &= ~(FLAGBIT_I | FLAGBIT_U | FLAGBIT_PM);
  1126. pushpc (old_psw);
  1127. pushpc (regs.r_pc);
  1128. regs.r_pc = mem_get_si (regs.r_intb + 4 * v);
  1129. }
  1130. cycles (6);
  1131. break;
  1132. case RXO_itof:
  1133. ma = GS ();
  1134. FPCLEAR ();
  1135. mb = rxfp_itof (ma, regs.r_fpsw);
  1136. FPCHECK ();
  1137. tprintf("(float) %d = %x\n", ma, mb);
  1138. PD (mb);
  1139. set_sz (ma, 4);
  1140. E (2);
  1141. break;
  1142. case RXO_jsr:
  1143. case RXO_jsrrel:
  1144. {
  1145. #ifdef CYCLE_ACCURATE
  1146. int delta;
  1147. regs.m2m = 0;
  1148. #endif
  1149. v = GD ();
  1150. #ifdef CYCLE_ACCURATE
  1151. regs.link_register = regs.r_pc;
  1152. #endif
  1153. pushpc (get_reg (pc));
  1154. if (opcode->id == RXO_jsrrel)
  1155. v += regs.r_pc;
  1156. #ifdef CYCLE_ACCURATE
  1157. delta = v - regs.r_pc;
  1158. #endif
  1159. put_reg (pc, v);
  1160. #ifdef CYCLE_ACCURATE
  1161. /* Note: docs say 3, chip says 2 */
  1162. if (delta >= 0 && delta < 16)
  1163. {
  1164. tprintf ("near forward jsr bonus\n");
  1165. cycles (2);
  1166. }
  1167. else
  1168. {
  1169. branch_alignment_penalty = 1;
  1170. cycles (3);
  1171. }
  1172. regs.fast_return = 1;
  1173. #endif
  1174. }
  1175. break;
  1176. case RXO_machi:
  1177. ll = (long long)(signed short)(GS() >> 16) * (long long)(signed short)(GS2 () >> 16);
  1178. ll <<= 16;
  1179. put_reg64 (acc64, ll + regs.r_acc);
  1180. E1;
  1181. break;
  1182. case RXO_maclo:
  1183. ll = (long long)(signed short)(GS()) * (long long)(signed short)(GS2 ());
  1184. ll <<= 16;
  1185. put_reg64 (acc64, ll + regs.r_acc);
  1186. E1;
  1187. break;
  1188. case RXO_max:
  1189. mb = GS();
  1190. ma = GD();
  1191. if (ma > mb)
  1192. PD (ma);
  1193. else
  1194. PD (mb);
  1195. E (1);
  1196. break;
  1197. case RXO_min:
  1198. mb = GS();
  1199. ma = GD();
  1200. if (ma < mb)
  1201. PD (ma);
  1202. else
  1203. PD (mb);
  1204. E (1);
  1205. break;
  1206. case RXO_mov:
  1207. v = GS ();
  1208. if (opcode->op[1].type == RX_Operand_Register
  1209. && opcode->op[1].reg == 17 /* PC */)
  1210. {
  1211. /* Special case. We want the address of the insn, not the
  1212. address of the next insn. */
  1213. v = opcode_pc;
  1214. }
  1215. if (opcode->op[0].type == RX_Operand_Register
  1216. && opcode->op[0].reg == 16 /* PSW */)
  1217. {
  1218. /* Special case, LDC and POPC can't ever modify PM. */
  1219. int pm = regs.r_psw & FLAGBIT_PM;
  1220. v &= ~ FLAGBIT_PM;
  1221. v |= pm;
  1222. if (pm)
  1223. {
  1224. v &= ~ (FLAGBIT_I | FLAGBIT_U | FLAGBITS_IPL);
  1225. v |= pm;
  1226. }
  1227. }
  1228. if (FLAG_PM)
  1229. {
  1230. /* various things can't be changed in user mode. */
  1231. if (opcode->op[0].type == RX_Operand_Register)
  1232. if (opcode->op[0].reg == 32)
  1233. {
  1234. v &= ~ (FLAGBIT_I | FLAGBIT_U | FLAGBITS_IPL);
  1235. v |= regs.r_psw & (FLAGBIT_I | FLAGBIT_U | FLAGBITS_IPL);
  1236. }
  1237. if (opcode->op[0].reg == 34 /* ISP */
  1238. || opcode->op[0].reg == 37 /* BPSW */
  1239. || opcode->op[0].reg == 39 /* INTB */
  1240. || opcode->op[0].reg == 38 /* VCT */)
  1241. /* These are ignored. */
  1242. break;
  1243. }
  1244. if (OM(0) && OM(1))
  1245. cycles (2);
  1246. else
  1247. cycles (1);
  1248. PD (v);
  1249. #ifdef CYCLE_ACCURATE
  1250. if ((opcode->op[0].type == RX_Operand_Predec
  1251. && opcode->op[1].type == RX_Operand_Register)
  1252. || (opcode->op[0].type == RX_Operand_Postinc
  1253. && opcode->op[1].type == RX_Operand_Register))
  1254. {
  1255. /* Special case: push reg doesn't cause a memory stall. */
  1256. memory_dest = 0;
  1257. tprintf("push special case\n");
  1258. }
  1259. #endif
  1260. set_sz (v, DSZ());
  1261. break;
  1262. case RXO_movbi:
  1263. PD (GS ());
  1264. cycles (1);
  1265. break;
  1266. case RXO_movbir:
  1267. PS (GD ());
  1268. cycles (1);
  1269. break;
  1270. case RXO_mul:
  1271. v = US2 ();
  1272. ll = (unsigned long long) US1() * (unsigned long long) v;
  1273. PD(ll);
  1274. E (1);
  1275. break;
  1276. case RXO_mulhi:
  1277. v = GS2 ();
  1278. ll = (long long)(signed short)(GS() >> 16) * (long long)(signed short)(v >> 16);
  1279. ll <<= 16;
  1280. put_reg64 (acc64, ll);
  1281. E1;
  1282. break;
  1283. case RXO_mullo:
  1284. v = GS2 ();
  1285. ll = (long long)(signed short)(GS()) * (long long)(signed short)(v);
  1286. ll <<= 16;
  1287. put_reg64 (acc64, ll);
  1288. E1;
  1289. break;
  1290. case RXO_mvfachi:
  1291. PD (get_reg (acchi));
  1292. E1;
  1293. break;
  1294. case RXO_mvfaclo:
  1295. PD (get_reg (acclo));
  1296. E1;
  1297. break;
  1298. case RXO_mvfacmi:
  1299. PD (get_reg (accmi));
  1300. E1;
  1301. break;
  1302. case RXO_mvtachi:
  1303. put_reg (acchi, GS ());
  1304. E1;
  1305. break;
  1306. case RXO_mvtaclo:
  1307. put_reg (acclo, GS ());
  1308. E1;
  1309. break;
  1310. case RXO_mvtipl:
  1311. regs.r_psw &= ~ FLAGBITS_IPL;
  1312. regs.r_psw |= (GS () << FLAGSHIFT_IPL) & FLAGBITS_IPL;
  1313. E1;
  1314. break;
  1315. case RXO_nop:
  1316. case RXO_nop2:
  1317. case RXO_nop3:
  1318. case RXO_nop4:
  1319. case RXO_nop5:
  1320. case RXO_nop6:
  1321. case RXO_nop7:
  1322. E1;
  1323. break;
  1324. case RXO_or:
  1325. LOGIC_OP (|);
  1326. break;
  1327. case RXO_popm:
  1328. /* POPM cannot pop R0 (sp). */
  1329. if (opcode->op[1].reg == 0 || opcode->op[2].reg == 0)
  1330. EXCEPTION (EX_UNDEFINED);
  1331. if (opcode->op[1].reg >= opcode->op[2].reg)
  1332. {
  1333. regs.r_pc = opcode_pc;
  1334. DO_RETURN (RX_MAKE_STOPPED (SIGILL));
  1335. }
  1336. for (v = opcode->op[1].reg; v <= opcode->op[2].reg; v++)
  1337. {
  1338. cycles (1);
  1339. RLD (v);
  1340. put_reg (v, pop ());
  1341. }
  1342. break;
  1343. case RXO_pushm:
  1344. /* PUSHM cannot push R0 (sp). */
  1345. if (opcode->op[1].reg == 0 || opcode->op[2].reg == 0)
  1346. EXCEPTION (EX_UNDEFINED);
  1347. if (opcode->op[1].reg >= opcode->op[2].reg)
  1348. {
  1349. regs.r_pc = opcode_pc;
  1350. return RX_MAKE_STOPPED (SIGILL);
  1351. }
  1352. for (v = opcode->op[2].reg; v >= opcode->op[1].reg; v--)
  1353. {
  1354. RL (v);
  1355. push (get_reg (v));
  1356. }
  1357. cycles (opcode->op[2].reg - opcode->op[1].reg + 1);
  1358. break;
  1359. case RXO_racw:
  1360. ll = get_reg64 (acc64) << GS ();
  1361. ll += 0x80000000ULL;
  1362. if ((signed long long)ll > (signed long long)0x00007fff00000000ULL)
  1363. ll = 0x00007fff00000000ULL;
  1364. else if ((signed long long)ll < (signed long long)0xffff800000000000ULL)
  1365. ll = 0xffff800000000000ULL;
  1366. else
  1367. ll &= 0xffffffff00000000ULL;
  1368. put_reg64 (acc64, ll);
  1369. E1;
  1370. break;
  1371. case RXO_rte:
  1372. PRIVILEDGED ();
  1373. regs.r_pc = poppc ();
  1374. regs.r_psw = poppc ();
  1375. if (FLAG_PM)
  1376. regs.r_psw |= FLAGBIT_U;
  1377. #ifdef CYCLE_ACCURATE
  1378. regs.fast_return = 0;
  1379. cycles (6);
  1380. #endif
  1381. break;
  1382. case RXO_revl:
  1383. uma = GS ();
  1384. umb = (((uma >> 24) & 0xff)
  1385. | ((uma >> 8) & 0xff00)
  1386. | ((uma << 8) & 0xff0000)
  1387. | ((uma << 24) & 0xff000000UL));
  1388. PD (umb);
  1389. E1;
  1390. break;
  1391. case RXO_revw:
  1392. uma = GS ();
  1393. umb = (((uma >> 8) & 0x00ff00ff)
  1394. | ((uma << 8) & 0xff00ff00UL));
  1395. PD (umb);
  1396. E1;
  1397. break;
  1398. case RXO_rmpa:
  1399. RL(4);
  1400. RL(5);
  1401. #ifdef CYCLE_ACCURATE
  1402. tx = regs.r[3];
  1403. #endif
  1404. while (regs.r[3] != 0)
  1405. {
  1406. long long tmp;
  1407. switch (opcode->size)
  1408. {
  1409. case RX_Long:
  1410. ma = mem_get_si (regs.r[1]);
  1411. mb = mem_get_si (regs.r[2]);
  1412. regs.r[1] += 4;
  1413. regs.r[2] += 4;
  1414. break;
  1415. case RX_Word:
  1416. ma = sign_ext (mem_get_hi (regs.r[1]), 16);
  1417. mb = sign_ext (mem_get_hi (regs.r[2]), 16);
  1418. regs.r[1] += 2;
  1419. regs.r[2] += 2;
  1420. break;
  1421. case RX_Byte:
  1422. ma = sign_ext (mem_get_qi (regs.r[1]), 8);
  1423. mb = sign_ext (mem_get_qi (regs.r[2]), 8);
  1424. regs.r[1] += 1;
  1425. regs.r[2] += 1;
  1426. break;
  1427. default:
  1428. abort ();
  1429. }
  1430. /* We do the multiply as a signed value. */
  1431. sll = (long long)ma * (long long)mb;
  1432. tprintf(" %016llx = %d * %d\n", sll, ma, mb);
  1433. /* but we do the sum as unsigned, while sign extending the operands. */
  1434. tmp = regs.r[4] + (sll & 0xffffffffUL);
  1435. regs.r[4] = tmp & 0xffffffffUL;
  1436. tmp >>= 32;
  1437. sll >>= 32;
  1438. tmp += regs.r[5] + (sll & 0xffffffffUL);
  1439. regs.r[5] = tmp & 0xffffffffUL;
  1440. tmp >>= 32;
  1441. sll >>= 32;
  1442. tmp += regs.r[6] + (sll & 0xffffffffUL);
  1443. regs.r[6] = tmp & 0xffffffffUL;
  1444. tprintf("%08lx\033[36m%08lx\033[0m%08lx\n",
  1445. (unsigned long) regs.r[6],
  1446. (unsigned long) regs.r[5],
  1447. (unsigned long) regs.r[4]);
  1448. regs.r[3] --;
  1449. }
  1450. if (regs.r[6] & 0x00008000)
  1451. regs.r[6] |= 0xffff0000UL;
  1452. else
  1453. regs.r[6] &= 0x0000ffff;
  1454. ma = (regs.r[6] & 0x80000000UL) ? FLAGBIT_S : 0;
  1455. if (regs.r[6] != 0 && regs.r[6] != 0xffffffffUL)
  1456. set_flags (FLAGBIT_O|FLAGBIT_S, ma | FLAGBIT_O);
  1457. else
  1458. set_flags (FLAGBIT_O|FLAGBIT_S, ma);
  1459. #ifdef CYCLE_ACCURATE
  1460. switch (opcode->size)
  1461. {
  1462. case RX_Long:
  1463. cycles (6 + 4 * tx);
  1464. break;
  1465. case RX_Word:
  1466. cycles (6 + 5 * (tx / 2) + 4 * (tx % 2));
  1467. break;
  1468. case RX_Byte:
  1469. cycles (6 + 7 * (tx / 4) + 4 * (tx % 4));
  1470. break;
  1471. default:
  1472. abort ();
  1473. }
  1474. #endif
  1475. break;
  1476. case RXO_rolc:
  1477. v = GD ();
  1478. ma = v & 0x80000000UL;
  1479. v <<= 1;
  1480. v |= carry;
  1481. set_szc (v, 4, ma);
  1482. PD (v);
  1483. E1;
  1484. break;
  1485. case RXO_rorc:
  1486. uma = GD ();
  1487. mb = uma & 1;
  1488. uma >>= 1;
  1489. uma |= (carry ? 0x80000000UL : 0);
  1490. set_szc (uma, 4, mb);
  1491. PD (uma);
  1492. E1;
  1493. break;
  1494. case RXO_rotl:
  1495. mb = GS ();
  1496. uma = GD ();
  1497. if (mb)
  1498. {
  1499. uma = (uma << mb) | (uma >> (32-mb));
  1500. mb = uma & 1;
  1501. }
  1502. set_szc (uma, 4, mb);
  1503. PD (uma);
  1504. E1;
  1505. break;
  1506. case RXO_rotr:
  1507. mb = GS ();
  1508. uma = GD ();
  1509. if (mb)
  1510. {
  1511. uma = (uma >> mb) | (uma << (32-mb));
  1512. mb = uma & 0x80000000;
  1513. }
  1514. set_szc (uma, 4, mb);
  1515. PD (uma);
  1516. E1;
  1517. break;
  1518. case RXO_round:
  1519. ma = GS ();
  1520. FPCLEAR ();
  1521. mb = rxfp_ftoi (ma, regs.r_fpsw);
  1522. FPCHECK ();
  1523. PD (mb);
  1524. tprintf("(int) %g = %d\n", int2float(ma), mb);
  1525. set_sz (mb, 4);
  1526. E (2);
  1527. break;
  1528. case RXO_rts:
  1529. {
  1530. #ifdef CYCLE_ACCURATE
  1531. int cyc = 5;
  1532. #endif
  1533. regs.r_pc = poppc ();
  1534. #ifdef CYCLE_ACCURATE
  1535. /* Note: specs say 5, chip says 3. */
  1536. if (regs.fast_return && regs.link_register == regs.r_pc)
  1537. {
  1538. #ifdef WITH_PROFILE
  1539. fast_returns ++;
  1540. #endif
  1541. tprintf("fast return bonus\n");
  1542. cyc -= 2;
  1543. }
  1544. cycles (cyc);
  1545. regs.fast_return = 0;
  1546. branch_alignment_penalty = 1;
  1547. #endif
  1548. }
  1549. break;
  1550. case RXO_rtsd:
  1551. if (opcode->op[2].type == RX_Operand_Register)
  1552. {
  1553. int i;
  1554. /* RTSD cannot pop R0 (sp). */
  1555. put_reg (0, get_reg (0) + GS() - (opcode->op[0].reg-opcode->op[2].reg+1)*4);
  1556. if (opcode->op[2].reg == 0)
  1557. EXCEPTION (EX_UNDEFINED);
  1558. #ifdef CYCLE_ACCURATE
  1559. tx = opcode->op[0].reg - opcode->op[2].reg + 1;
  1560. #endif
  1561. for (i = opcode->op[2].reg; i <= opcode->op[0].reg; i ++)
  1562. {
  1563. RLD (i);
  1564. put_reg (i, pop ());
  1565. }
  1566. }
  1567. else
  1568. {
  1569. #ifdef CYCLE_ACCURATE
  1570. tx = 0;
  1571. #endif
  1572. put_reg (0, get_reg (0) + GS());
  1573. }
  1574. put_reg (pc, poppc());
  1575. #ifdef CYCLE_ACCURATE
  1576. if (regs.fast_return && regs.link_register == regs.r_pc)
  1577. {
  1578. tprintf("fast return bonus\n");
  1579. #ifdef WITH_PROFILE
  1580. fast_returns ++;
  1581. #endif
  1582. cycles (tx < 3 ? 3 : tx + 1);
  1583. }
  1584. else
  1585. {
  1586. cycles (tx < 5 ? 5 : tx + 1);
  1587. }
  1588. regs.fast_return = 0;
  1589. branch_alignment_penalty = 1;
  1590. #endif
  1591. break;
  1592. case RXO_sat:
  1593. if (FLAG_O && FLAG_S)
  1594. PD (0x7fffffffUL);
  1595. else if (FLAG_O && ! FLAG_S)
  1596. PD (0x80000000UL);
  1597. E1;
  1598. break;
  1599. case RXO_satr:
  1600. if (FLAG_O && ! FLAG_S)
  1601. {
  1602. put_reg (6, 0x0);
  1603. put_reg (5, 0x7fffffff);
  1604. put_reg (4, 0xffffffff);
  1605. }
  1606. else if (FLAG_O && FLAG_S)
  1607. {
  1608. put_reg (6, 0xffffffff);
  1609. put_reg (5, 0x80000000);
  1610. put_reg (4, 0x0);
  1611. }
  1612. E1;
  1613. break;
  1614. case RXO_sbb:
  1615. MATH_OP (-, ! carry);
  1616. break;
  1617. case RXO_sccnd:
  1618. if (GS())
  1619. PD (1);
  1620. else
  1621. PD (0);
  1622. E1;
  1623. break;
  1624. case RXO_scmpu:
  1625. #ifdef CYCLE_ACCURATE
  1626. tx = regs.r[3];
  1627. #endif
  1628. while (regs.r[3] != 0)
  1629. {
  1630. uma = mem_get_qi (regs.r[1] ++);
  1631. umb = mem_get_qi (regs.r[2] ++);
  1632. regs.r[3] --;
  1633. if (uma != umb || uma == 0)
  1634. break;
  1635. }
  1636. if (uma == umb)
  1637. set_zc (1, 1);
  1638. else
  1639. set_zc (0, ((int)uma - (int)umb) >= 0);
  1640. cycles (2 + 4 * (tx / 4) + 4 * (tx % 4));
  1641. break;
  1642. case RXO_setpsw:
  1643. v = 1 << opcode->op[0].reg;
  1644. if (FLAG_PM
  1645. && (v == FLAGBIT_I
  1646. || v == FLAGBIT_U))
  1647. break;
  1648. regs.r_psw |= v;
  1649. cycles (1);
  1650. break;
  1651. case RXO_smovb:
  1652. RL (3);
  1653. #ifdef CYCLE_ACCURATE
  1654. tx = regs.r[3];
  1655. #endif
  1656. while (regs.r[3])
  1657. {
  1658. uma = mem_get_qi (regs.r[2] --);
  1659. mem_put_qi (regs.r[1]--, uma);
  1660. regs.r[3] --;
  1661. }
  1662. #ifdef CYCLE_ACCURATE
  1663. if (tx > 3)
  1664. cycles (6 + 3 * (tx / 4) + 3 * (tx % 4));
  1665. else
  1666. cycles (2 + 3 * (tx % 4));
  1667. #endif
  1668. break;
  1669. case RXO_smovf:
  1670. RL (3);
  1671. #ifdef CYCLE_ACCURATE
  1672. tx = regs.r[3];
  1673. #endif
  1674. while (regs.r[3])
  1675. {
  1676. uma = mem_get_qi (regs.r[2] ++);
  1677. mem_put_qi (regs.r[1]++, uma);
  1678. regs.r[3] --;
  1679. }
  1680. cycles (2 + 3 * (int)(tx / 4) + 3 * (tx % 4));
  1681. break;
  1682. case RXO_smovu:
  1683. #ifdef CYCLE_ACCURATE
  1684. tx = regs.r[3];
  1685. #endif
  1686. while (regs.r[3] != 0)
  1687. {
  1688. uma = mem_get_qi (regs.r[2] ++);
  1689. mem_put_qi (regs.r[1]++, uma);
  1690. regs.r[3] --;
  1691. if (uma == 0)
  1692. break;
  1693. }
  1694. cycles (2 + 3 * (int)(tx / 4) + 3 * (tx % 4));
  1695. break;
  1696. case RXO_shar: /* d = ma >> mb */
  1697. SHIFT_OP (sll, int, mb, >>=, 1);
  1698. E (1);
  1699. break;
  1700. case RXO_shll: /* d = ma << mb */
  1701. SHIFT_OP (ll, int, mb, <<=, 0x80000000UL);
  1702. E (1);
  1703. break;
  1704. case RXO_shlr: /* d = ma >> mb */
  1705. SHIFT_OP (ll, unsigned int, mb, >>=, 1);
  1706. E (1);
  1707. break;
  1708. case RXO_sstr:
  1709. RL (3);
  1710. #ifdef CYCLE_ACCURATE
  1711. tx = regs.r[3];
  1712. #endif
  1713. switch (opcode->size)
  1714. {
  1715. case RX_Long:
  1716. while (regs.r[3] != 0)
  1717. {
  1718. mem_put_si (regs.r[1], regs.r[2]);
  1719. regs.r[1] += 4;
  1720. regs.r[3] --;
  1721. }
  1722. cycles (2 + tx);
  1723. break;
  1724. case RX_Word:
  1725. while (regs.r[3] != 0)
  1726. {
  1727. mem_put_hi (regs.r[1], regs.r[2]);
  1728. regs.r[1] += 2;
  1729. regs.r[3] --;
  1730. }
  1731. cycles (2 + (int)(tx / 2) + tx % 2);
  1732. break;
  1733. case RX_Byte:
  1734. while (regs.r[3] != 0)
  1735. {
  1736. mem_put_qi (regs.r[1], regs.r[2]);
  1737. regs.r[1] ++;
  1738. regs.r[3] --;
  1739. }
  1740. cycles (2 + (int)(tx / 4) + tx % 4);
  1741. break;
  1742. default:
  1743. abort ();
  1744. }
  1745. break;
  1746. case RXO_stcc:
  1747. if (GS2())
  1748. PD (GS ());
  1749. E1;
  1750. break;
  1751. case RXO_stop:
  1752. PRIVILEDGED ();
  1753. regs.r_psw |= FLAGBIT_I;
  1754. DO_RETURN (RX_MAKE_STOPPED(0));
  1755. case RXO_sub:
  1756. MATH_OP (-, 0);
  1757. break;
  1758. case RXO_suntil:
  1759. RL(3);
  1760. #ifdef CYCLE_ACCURATE
  1761. tx = 0;
  1762. #endif
  1763. if (regs.r[3] == 0)
  1764. {
  1765. cycles (3);
  1766. break;
  1767. }
  1768. switch (opcode->size)
  1769. {
  1770. case RX_Long:
  1771. uma = get_reg (2);
  1772. while (regs.r[3] != 0)
  1773. {
  1774. regs.r[3] --;
  1775. umb = mem_get_si (get_reg (1));
  1776. regs.r[1] += 4;
  1777. #ifdef CYCLE_ACCURATE
  1778. tx ++;
  1779. #endif
  1780. if (umb == uma)
  1781. break;
  1782. }
  1783. #ifdef CYCLE_ACCURATE
  1784. cycles (3 + 3 * tx);
  1785. #endif
  1786. break;
  1787. case RX_Word:
  1788. uma = get_reg (2) & 0xffff;
  1789. while (regs.r[3] != 0)
  1790. {
  1791. regs.r[3] --;
  1792. umb = mem_get_hi (get_reg (1));
  1793. regs.r[1] += 2;
  1794. #ifdef CYCLE_ACCURATE
  1795. tx ++;
  1796. #endif
  1797. if (umb == uma)
  1798. break;
  1799. }
  1800. #ifdef CYCLE_ACCURATE
  1801. cycles (3 + 3 * (tx / 2) + 3 * (tx % 2));
  1802. #endif
  1803. break;
  1804. case RX_Byte:
  1805. uma = get_reg (2) & 0xff;
  1806. while (regs.r[3] != 0)
  1807. {
  1808. regs.r[3] --;
  1809. umb = mem_get_qi (regs.r[1]);
  1810. regs.r[1] += 1;
  1811. #ifdef CYCLE_ACCURATE
  1812. tx ++;
  1813. #endif
  1814. if (umb == uma)
  1815. break;
  1816. }
  1817. #ifdef CYCLE_ACCURATE
  1818. cycles (3 + 3 * (tx / 4) + 3 * (tx % 4));
  1819. #endif
  1820. break;
  1821. default:
  1822. abort();
  1823. }
  1824. if (uma == umb)
  1825. set_zc (1, 1);
  1826. else
  1827. set_zc (0, ((int)uma - (int)umb) >= 0);
  1828. break;
  1829. case RXO_swhile:
  1830. RL(3);
  1831. #ifdef CYCLE_ACCURATE
  1832. tx = 0;
  1833. #endif
  1834. if (regs.r[3] == 0)
  1835. break;
  1836. switch (opcode->size)
  1837. {
  1838. case RX_Long:
  1839. uma = get_reg (2);
  1840. while (regs.r[3] != 0)
  1841. {
  1842. regs.r[3] --;
  1843. umb = mem_get_si (get_reg (1));
  1844. regs.r[1] += 4;
  1845. #ifdef CYCLE_ACCURATE
  1846. tx ++;
  1847. #endif
  1848. if (umb != uma)
  1849. break;
  1850. }
  1851. #ifdef CYCLE_ACCURATE
  1852. cycles (3 + 3 * tx);
  1853. #endif
  1854. break;
  1855. case RX_Word:
  1856. uma = get_reg (2) & 0xffff;
  1857. while (regs.r[3] != 0)
  1858. {
  1859. regs.r[3] --;
  1860. umb = mem_get_hi (get_reg (1));
  1861. regs.r[1] += 2;
  1862. #ifdef CYCLE_ACCURATE
  1863. tx ++;
  1864. #endif
  1865. if (umb != uma)
  1866. break;
  1867. }
  1868. #ifdef CYCLE_ACCURATE
  1869. cycles (3 + 3 * (tx / 2) + 3 * (tx % 2));
  1870. #endif
  1871. break;
  1872. case RX_Byte:
  1873. uma = get_reg (2) & 0xff;
  1874. while (regs.r[3] != 0)
  1875. {
  1876. regs.r[3] --;
  1877. umb = mem_get_qi (regs.r[1]);
  1878. regs.r[1] += 1;
  1879. #ifdef CYCLE_ACCURATE
  1880. tx ++;
  1881. #endif
  1882. if (umb != uma)
  1883. break;
  1884. }
  1885. #ifdef CYCLE_ACCURATE
  1886. cycles (3 + 3 * (tx / 4) + 3 * (tx % 4));
  1887. #endif
  1888. break;
  1889. default:
  1890. abort();
  1891. }
  1892. if (uma == umb)
  1893. set_zc (1, 1);
  1894. else
  1895. set_zc (0, ((int)uma - (int)umb) >= 0);
  1896. break;
  1897. case RXO_wait:
  1898. PRIVILEDGED ();
  1899. regs.r_psw |= FLAGBIT_I;
  1900. DO_RETURN (RX_MAKE_STOPPED(0));
  1901. case RXO_xchg:
  1902. #ifdef CYCLE_ACCURATE
  1903. regs.m2m = 0;
  1904. #endif
  1905. v = GS (); /* This is the memory operand, if any. */
  1906. PS (GD ()); /* and this may change the address register. */
  1907. PD (v);
  1908. E2;
  1909. #ifdef CYCLE_ACCURATE
  1910. /* all M cycles happen during xchg's cycles. */
  1911. memory_dest = 0;
  1912. memory_source = 0;
  1913. #endif
  1914. break;
  1915. case RXO_xor:
  1916. LOGIC_OP (^);
  1917. break;
  1918. default:
  1919. EXCEPTION (EX_UNDEFINED);
  1920. }
  1921. #ifdef CYCLE_ACCURATE
  1922. regs.m2m = 0;
  1923. if (memory_source)
  1924. regs.m2m |= M2M_SRC;
  1925. if (memory_dest)
  1926. regs.m2m |= M2M_DST;
  1927. regs.rt = new_rt;
  1928. new_rt = -1;
  1929. #endif
  1930. #ifdef WITH_PROFILE
  1931. if (prev_cycle_count == regs.cycle_count)
  1932. {
  1933. printf("Cycle count not updated! id %s\n", id_names[opcode->id]);
  1934. abort ();
  1935. }
  1936. #endif
  1937. #ifdef WITH_PROFILE
  1938. if (running_benchmark)
  1939. {
  1940. int omap = op_lookup (opcode->op[0].type, opcode->op[1].type, opcode->op[2].type);
  1941. cycles_per_id[opcode->id][omap] += regs.cycle_count - prev_cycle_count;
  1942. times_per_id[opcode->id][omap] ++;
  1943. times_per_pair[prev_opcode_id][po0][opcode->id][omap] ++;
  1944. prev_opcode_id = opcode->id;
  1945. po0 = omap;
  1946. }
  1947. #endif
  1948. return RX_MAKE_STEPPED ();
  1949. }
  1950. #ifdef WITH_PROFILE
  1951. void
  1952. reset_pipeline_stats (void)
  1953. {
  1954. memset (cycles_per_id, 0, sizeof(cycles_per_id));
  1955. memset (times_per_id, 0, sizeof(times_per_id));
  1956. memory_stalls = 0;
  1957. register_stalls = 0;
  1958. branch_stalls = 0;
  1959. branch_alignment_stalls = 0;
  1960. fast_returns = 0;
  1961. memset (times_per_pair, 0, sizeof(times_per_pair));
  1962. running_benchmark = 1;
  1963. benchmark_start_cycle = regs.cycle_count;
  1964. }
  1965. void
  1966. halt_pipeline_stats (void)
  1967. {
  1968. running_benchmark = 0;
  1969. benchmark_end_cycle = regs.cycle_count;
  1970. }
  1971. #endif
  1972. void
  1973. pipeline_stats (void)
  1974. {
  1975. #ifdef WITH_PROFILE
  1976. int i, o1;
  1977. int p, p1;
  1978. #endif
  1979. #ifdef CYCLE_ACCURATE
  1980. if (verbose == 1)
  1981. {
  1982. printf ("cycles: %llu\n", regs.cycle_count);
  1983. return;
  1984. }
  1985. printf ("cycles: %13s\n", comma (regs.cycle_count));
  1986. #endif
  1987. #ifdef WITH_PROFILE
  1988. if (benchmark_start_cycle)
  1989. printf ("bmark: %13s\n", comma (benchmark_end_cycle - benchmark_start_cycle));
  1990. printf("\n");
  1991. for (i = 0; i < N_RXO; i++)
  1992. for (o1 = 0; o1 < N_MAP; o1 ++)
  1993. if (times_per_id[i][o1])
  1994. printf("%13s %13s %7.2f %s %s\n",
  1995. comma (cycles_per_id[i][o1]),
  1996. comma (times_per_id[i][o1]),
  1997. (double)cycles_per_id[i][o1] / times_per_id[i][o1],
  1998. op_cache_string(o1),
  1999. id_names[i]+4);
  2000. printf("\n");
  2001. for (p = 0; p < N_RXO; p ++)
  2002. for (p1 = 0; p1 < N_MAP; p1 ++)
  2003. for (i = 0; i < N_RXO; i ++)
  2004. for (o1 = 0; o1 < N_MAP; o1 ++)
  2005. if (times_per_pair[p][p1][i][o1])
  2006. {
  2007. printf("%13s %s %-9s -> %s %s\n",
  2008. comma (times_per_pair[p][p1][i][o1]),
  2009. op_cache_string(p1),
  2010. id_names[p]+4,
  2011. op_cache_string(o1),
  2012. id_names[i]+4);
  2013. }
  2014. printf("\n");
  2015. printf("%13s memory stalls\n", comma (memory_stalls));
  2016. printf("%13s register stalls\n", comma (register_stalls));
  2017. printf("%13s branches taken (non-return)\n", comma (branch_stalls));
  2018. printf("%13s branch alignment stalls\n", comma (branch_alignment_stalls));
  2019. printf("%13s fast returns\n", comma (fast_returns));
  2020. #endif
  2021. }