reg.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682
  1. /* reg.c --- register set model for M32C simulator.
  2. Copyright (C) 2005-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 "cpu.h"
  21. int verbose = 0;
  22. int trace = 0;
  23. int enable_counting = 0;
  24. int in_gdb = 1;
  25. regs_type regs;
  26. int addr_mask = 0xffff;
  27. int membus_mask = 0xfffff;
  28. int m32c_cpu = 0;
  29. int step_result;
  30. unsigned int heapbottom = 0;
  31. unsigned int heaptop = 0;
  32. char *reg_names[] = {
  33. "mem",
  34. "r0", "r0h", "r0l",
  35. "r1", "r1h", "r1l",
  36. "r2", "r2r0",
  37. "r3", "r3r1",
  38. "r3r1r2r0",
  39. "r3r2r1r0",
  40. "a0",
  41. "a1", "a1a0",
  42. "sb", "fb",
  43. "intb", "intbl", "intbh",
  44. "sp", "usp", "isp", "pc", "flags"
  45. };
  46. int reg_bytes[] = {
  47. 0,
  48. 2, 1, 1,
  49. 2, 1, 1,
  50. 2, 4,
  51. 2, 4,
  52. 8,
  53. 8,
  54. 2,
  55. 2, 4,
  56. 2, 2,
  57. 2, 1, 3,
  58. 2, 2, 2, 3, 2
  59. };
  60. unsigned int b2mask[] = { 0, 0xff, 0xffff, 0xffffff, 0xffffffff };
  61. unsigned int b2signbit[] = { 0, (1 << 7), (1 << 15), (1 << 24), (1 << 31) };
  62. int b2maxsigned[] = { 0, 0x7f, 0x7fff, 0x7fffff, 0x7fffffff };
  63. int b2minsigned[] = { 0, -128, -32768, -8388608, -2147483647 - 1 };
  64. static regs_type oldregs;
  65. int m32c_opcode_pc;
  66. void
  67. init_regs (void)
  68. {
  69. memset (&regs, 0, sizeof (regs));
  70. memset (&oldregs, 0, sizeof (oldregs));
  71. }
  72. void
  73. set_pointer_width (int bytes)
  74. {
  75. if (bytes == 2)
  76. {
  77. addr_mask = 0xffff;
  78. membus_mask = 0x000fffff;
  79. reg_bytes[a0] = reg_bytes[a1] = reg_bytes[sb] = reg_bytes[fb] =
  80. reg_bytes[sp] = reg_bytes[usp] = reg_bytes[isp] = 2;
  81. }
  82. else
  83. {
  84. addr_mask = 0xffffff;
  85. membus_mask = 0x00ffffff;
  86. reg_bytes[a0] = reg_bytes[a1] = reg_bytes[sb] = reg_bytes[fb] =
  87. reg_bytes[sp] = reg_bytes[usp] = reg_bytes[isp] = 3;
  88. }
  89. }
  90. void
  91. m32c_set_cpu (int cpu)
  92. {
  93. switch (cpu)
  94. {
  95. case CPU_R8C:
  96. case CPU_M16C:
  97. set_pointer_width (2);
  98. decode_opcode = decode_r8c;
  99. break;
  100. case CPU_M32CM:
  101. case CPU_M32C:
  102. set_pointer_width (3);
  103. decode_opcode = decode_m32c;
  104. break;
  105. default:
  106. abort ();
  107. }
  108. m32c_cpu = cpu;
  109. }
  110. static unsigned int
  111. get_reg_i (reg_id id)
  112. {
  113. reg_bank_type *b = regs.r + (FLAG_B ? 1 : 0);
  114. switch (id)
  115. {
  116. case r0:
  117. return b->r_r0;
  118. case r0h:
  119. return b->r_r0 >> 8;
  120. case r0l:
  121. return b->r_r0 & 0xff;
  122. case r1:
  123. return b->r_r1;
  124. case r1h:
  125. return b->r_r1 >> 8;
  126. case r1l:
  127. return b->r_r1 & 0xff;
  128. case r2:
  129. return b->r_r2;
  130. case r2r0:
  131. return b->r_r2 * 65536 + b->r_r0;
  132. case r3:
  133. return b->r_r3;
  134. case r3r1:
  135. return b->r_r3 * 65536 + b->r_r1;
  136. case a0:
  137. return b->r_a0 & addr_mask;
  138. case a1:
  139. return b->r_a1 & addr_mask;
  140. case a1a0:
  141. return (b->r_a1 & 0xffff) * 65536 | (b->r_a0 & 0xffff);
  142. case sb:
  143. return b->r_sb & addr_mask;
  144. case fb:
  145. return b->r_fb & addr_mask;
  146. case intb:
  147. return regs.r_intbh * 65536 + regs.r_intbl;
  148. case intbl:
  149. return regs.r_intbl;
  150. case intbh:
  151. return regs.r_intbh;
  152. case sp:
  153. return ((regs.r_flags & FLAGBIT_U) ? regs.r_usp : regs.
  154. r_isp) & addr_mask;
  155. case usp:
  156. return regs.r_usp & addr_mask;
  157. case isp:
  158. return regs.r_isp & addr_mask;
  159. case pc:
  160. return regs.r_pc & membus_mask;
  161. case flags:
  162. return regs.r_flags;
  163. default:
  164. abort ();
  165. }
  166. }
  167. unsigned int
  168. get_reg (reg_id id)
  169. {
  170. unsigned int rv = get_reg_i (id);
  171. if (trace > ((id != pc && id != fb && id != sp) ? 0 : 1))
  172. printf ("get_reg (%s) = %0*x\n", reg_names[id], reg_bytes[id] * 2, rv);
  173. return rv;
  174. }
  175. DI
  176. get_reg_ll (reg_id id)
  177. {
  178. reg_bank_type *b = regs.r + (FLAG_B ? 1 : 0);
  179. switch (id)
  180. {
  181. case r3r1r2r0:
  182. return ((DI) b->r_r3 << 48
  183. | (DI) b->r_r1 << 32 | (DI) b->r_r2 << 16 | (DI) b->r_r0);
  184. case r3r2r1r0:
  185. return ((DI) b->r_r3 << 48
  186. | (DI) b->r_r2 << 32 | (DI) b->r_r1 << 16 | (DI) b->r_r0);
  187. default:
  188. return get_reg (id);
  189. }
  190. }
  191. static int highest_sp = 0, lowest_sp = 0xffffff;
  192. void
  193. stack_heap_stats (void)
  194. {
  195. printf ("heap: %08x - %08x (%d bytes)\n", heapbottom, heaptop,
  196. heaptop - heapbottom);
  197. printf ("stack: %08x - %08x (%d bytes)\n", lowest_sp, highest_sp,
  198. highest_sp - lowest_sp);
  199. }
  200. void
  201. put_reg (reg_id id, unsigned int v)
  202. {
  203. reg_bank_type *b = regs.r + (FLAG_B ? 1 : 0);
  204. if (trace > ((id != pc) ? 0 : 1))
  205. printf ("put_reg (%s) = %0*x\n", reg_names[id], reg_bytes[id] * 2, v);
  206. switch (id)
  207. {
  208. case r0:
  209. b->r_r0 = v;
  210. break;
  211. case r0h:
  212. b->r_r0 = (b->r_r0 & 0xff) | (v << 8);
  213. break;
  214. case r0l:
  215. b->r_r0 = (b->r_r0 & 0xff00) | (v & 0xff);
  216. break;
  217. case r1:
  218. b->r_r1 = v;
  219. break;
  220. case r1h:
  221. b->r_r1 = (b->r_r1 & 0xff) | (v << 8);
  222. break;
  223. case r1l:
  224. b->r_r1 = (b->r_r1 & 0xff00) | (v & 0xff);
  225. break;
  226. case r2:
  227. b->r_r2 = v;
  228. break;
  229. case r2r0:
  230. b->r_r0 = v & 0xffff;
  231. b->r_r2 = v >> 16;
  232. break;
  233. case r3:
  234. b->r_r3 = v;
  235. break;
  236. case r3r1:
  237. b->r_r1 = v & 0xffff;
  238. b->r_r3 = v >> 16;
  239. break;
  240. case a0:
  241. b->r_a0 = v & addr_mask;
  242. break;
  243. case a1:
  244. b->r_a1 = v & addr_mask;
  245. break;
  246. case a1a0:
  247. b->r_a0 = v & 0xffff;
  248. b->r_a1 = v >> 16;
  249. break;
  250. case sb:
  251. b->r_sb = v & addr_mask;
  252. break;
  253. case fb:
  254. b->r_fb = v & addr_mask;
  255. break;
  256. case intb:
  257. regs.r_intbl = v & 0xffff;
  258. regs.r_intbh = v >> 16;
  259. break;
  260. case intbl:
  261. regs.r_intbl = v & 0xffff;
  262. break;
  263. case intbh:
  264. regs.r_intbh = v & 0xff;
  265. break;
  266. case sp:
  267. {
  268. SI *spp;
  269. if (regs.r_flags & FLAGBIT_U)
  270. spp = &regs.r_usp;
  271. else
  272. spp = &regs.r_isp;
  273. *spp = v & addr_mask;
  274. if (*spp < heaptop)
  275. {
  276. printf ("collision: pc %08lx heap %08x stack %08lx\n", regs.r_pc,
  277. heaptop, *spp);
  278. exit (1);
  279. }
  280. if (*spp < lowest_sp)
  281. lowest_sp = *spp;
  282. if (*spp > highest_sp)
  283. highest_sp = *spp;
  284. break;
  285. }
  286. case usp:
  287. regs.r_usp = v & addr_mask;
  288. break;
  289. case isp:
  290. regs.r_isp = v & addr_mask;
  291. break;
  292. case pc:
  293. regs.r_pc = v & membus_mask;
  294. break;
  295. case flags:
  296. regs.r_flags = v;
  297. break;
  298. default:
  299. abort ();
  300. }
  301. }
  302. int
  303. condition_true (int cond_id)
  304. {
  305. int f;
  306. if (A16)
  307. {
  308. static const char *cond_name[] = {
  309. "C", "C&!Z", "Z", "S",
  310. "!C", "!(C&!Z)", "!Z", "!S",
  311. "(S^O)|Z", "O", "!(S^O)", "unk",
  312. "!((S^O)|Z)", "!O", "S^O", "unk"
  313. };
  314. switch (cond_id & 15)
  315. {
  316. case 0:
  317. f = FLAG_C;
  318. break; /* GEU/C */
  319. case 1:
  320. f = FLAG_C & !FLAG_Z;
  321. break; /* GTU */
  322. case 2:
  323. f = FLAG_Z;
  324. break; /* EQ/Z */
  325. case 3:
  326. f = FLAG_S;
  327. break; /* N */
  328. case 4:
  329. f = !FLAG_C;
  330. break; /* LTU/NC */
  331. case 5:
  332. f = !(FLAG_C & !FLAG_Z);
  333. break; /* LEU */
  334. case 6:
  335. f = !FLAG_Z;
  336. break; /* NE/NZ */
  337. case 7:
  338. f = !FLAG_S;
  339. break; /* PZ */
  340. case 8:
  341. f = (FLAG_S ^ FLAG_O) | FLAG_Z;
  342. break; /* LE */
  343. case 9:
  344. f = FLAG_O;
  345. break; /* O */
  346. case 10:
  347. f = !(FLAG_S ^ FLAG_O);
  348. break; /* GE */
  349. case 12:
  350. f = !((FLAG_S ^ FLAG_O) | FLAG_Z);
  351. break; /* GT */
  352. case 13:
  353. f = !FLAG_O;
  354. break; /* NO */
  355. case 14:
  356. f = FLAG_S ^ FLAG_O;
  357. break; /* LT */
  358. default:
  359. f = 0;
  360. break;
  361. }
  362. if (trace)
  363. printf ("cond[%d] %s = %s\n", cond_id, cond_name[cond_id & 15],
  364. f ? "true" : "false");
  365. }
  366. else
  367. {
  368. static const char *cond_name[] = {
  369. "!C", "LEU", "!Z", "PZ",
  370. "!O", "GT", "GE", "?",
  371. "C", "GTU", "Z", "N",
  372. "O", "LE", "LT", "!?"
  373. };
  374. switch (cond_id & 15)
  375. {
  376. case 0:
  377. f = !FLAG_C;
  378. break; /* LTU/NC */
  379. case 1:
  380. f = !(FLAG_C & !FLAG_Z);
  381. break; /* LEU */
  382. case 2:
  383. f = !FLAG_Z;
  384. break; /* NE/NZ */
  385. case 3:
  386. f = !FLAG_S;
  387. break; /* PZ */
  388. case 4:
  389. f = !FLAG_O;
  390. break; /* NO */
  391. case 5:
  392. f = !((FLAG_S ^ FLAG_O) | FLAG_Z);
  393. break; /* GT */
  394. case 6:
  395. f = !(FLAG_S ^ FLAG_O);
  396. break; /* GE */
  397. case 8:
  398. f = FLAG_C;
  399. break; /* GEU/C */
  400. case 9:
  401. f = FLAG_C & !FLAG_Z;
  402. break; /* GTU */
  403. case 10:
  404. f = FLAG_Z;
  405. break; /* EQ/Z */
  406. case 11:
  407. f = FLAG_S;
  408. break; /* N */
  409. case 12:
  410. f = FLAG_O;
  411. break; /* O */
  412. case 13:
  413. f = (FLAG_S ^ FLAG_O) | FLAG_Z;
  414. break; /* LE */
  415. case 14:
  416. f = FLAG_S ^ FLAG_O;
  417. break; /* LT */
  418. default:
  419. f = 0;
  420. break;
  421. }
  422. if (trace)
  423. printf ("cond[%d] %s = %s\n", cond_id, cond_name[cond_id & 15],
  424. f ? "true" : "false");
  425. }
  426. return f;
  427. }
  428. void
  429. set_flags (int mask, int newbits)
  430. {
  431. int i;
  432. regs.r_flags &= ~mask;
  433. regs.r_flags |= newbits & mask;
  434. if (trace)
  435. {
  436. printf ("flags now \033[32m %d", (regs.r_flags >> (A16 ? 8 : 12)) & 7);
  437. for (i = 7; i >= 0; i--)
  438. if (regs.r_flags & (1 << i))
  439. putchar ("CDZSBOIU"[i]);
  440. else
  441. putchar ('-');
  442. printf ("\033[0m\n");
  443. }
  444. }
  445. void
  446. set_oszc (int value, int b, int c)
  447. {
  448. int mask = b2mask[b];
  449. int f = 0;
  450. if (c)
  451. f |= FLAGBIT_C;
  452. if ((value & mask) == 0)
  453. f |= FLAGBIT_Z;
  454. if (value & b2signbit[b])
  455. f |= FLAGBIT_S;
  456. if ((value > b2maxsigned[b]) || (value < b2minsigned[b]))
  457. f |= FLAGBIT_O;
  458. set_flags (FLAGBIT_Z | FLAGBIT_S | FLAGBIT_O | FLAGBIT_C, f);
  459. }
  460. void
  461. set_szc (int value, int b, int c)
  462. {
  463. int mask = b2mask[b];
  464. int f = 0;
  465. if (c)
  466. f |= FLAGBIT_C;
  467. if ((value & mask) == 0)
  468. f |= FLAGBIT_Z;
  469. if (value & b2signbit[b])
  470. f |= FLAGBIT_S;
  471. set_flags (FLAGBIT_Z | FLAGBIT_S | FLAGBIT_C, f);
  472. }
  473. void
  474. set_osz (int value, int b)
  475. {
  476. int mask = b2mask[b];
  477. int f = 0;
  478. if ((value & mask) == 0)
  479. f |= FLAGBIT_Z;
  480. if (value & b2signbit[b])
  481. f |= FLAGBIT_S;
  482. if (value & ~mask && (value & ~mask) != ~mask)
  483. f |= FLAGBIT_O;
  484. set_flags (FLAGBIT_Z | FLAGBIT_S | FLAGBIT_O, f);
  485. }
  486. void
  487. set_sz (int value, int b)
  488. {
  489. int mask = b2mask[b];
  490. int f = 0;
  491. if ((value & mask) == 0)
  492. f |= FLAGBIT_Z;
  493. if (value & b2signbit[b])
  494. f |= FLAGBIT_S;
  495. set_flags (FLAGBIT_Z | FLAGBIT_S, f);
  496. }
  497. void
  498. set_zc (int z, int c)
  499. {
  500. set_flags (FLAGBIT_C | FLAGBIT_Z,
  501. (c ? FLAGBIT_C : 0) | (z ? FLAGBIT_Z : 0));
  502. }
  503. void
  504. set_c (int c)
  505. {
  506. set_flags (FLAGBIT_C, c ? FLAGBIT_C : 0);
  507. }
  508. void
  509. put_reg_ll (reg_id id, DI v)
  510. {
  511. reg_bank_type *b = regs.r + (FLAG_B ? 1 : 0);
  512. switch (id)
  513. {
  514. case r3r1r2r0:
  515. b->r_r3 = v >> 48;
  516. b->r_r1 = v >> 32;
  517. b->r_r2 = v >> 16;
  518. b->r_r0 = v;
  519. break;
  520. case r3r2r1r0:
  521. b->r_r3 = v >> 48;
  522. b->r_r2 = v >> 32;
  523. b->r_r1 = v >> 16;
  524. b->r_r0 = v;
  525. break;
  526. default:
  527. put_reg (id, v);
  528. }
  529. }
  530. static void
  531. print_flags (int f)
  532. {
  533. int i;
  534. static char fn[] = "CDZSBOIU";
  535. printf ("%d.", (f >> 12) & 7);
  536. for (i = 7; i >= 0; i--)
  537. if (f & (1 << i))
  538. putchar (fn[i]);
  539. }
  540. #define TRC(f,n, id) \
  541. if (oldregs.f != regs.f) \
  542. { \
  543. printf(" %s %0*x:%0*x", n, \
  544. reg_bytes[id]*2, (unsigned int)oldregs.f, \
  545. reg_bytes[id]*2, (unsigned int)regs.f); \
  546. oldregs.f = regs.f; \
  547. }
  548. void
  549. trace_register_changes (void)
  550. {
  551. if (!trace)
  552. return;
  553. printf ("\033[36mREGS:");
  554. TRC (r[0].r_r0, "r0", r0);
  555. TRC (r[0].r_r1, "r1", r1);
  556. TRC (r[0].r_r2, "r2", r2);
  557. TRC (r[0].r_r3, "r3", r3);
  558. TRC (r[0].r_a0, "a0", a0);
  559. TRC (r[0].r_a1, "a1", a1);
  560. TRC (r[0].r_sb, "sb", sb);
  561. TRC (r[0].r_fb, "fb", fb);
  562. TRC (r[1].r_r0, "r0'", r0);
  563. TRC (r[1].r_r1, "r1'", r1);
  564. TRC (r[1].r_r2, "r2'", r2);
  565. TRC (r[1].r_r3, "r3'", r3);
  566. TRC (r[1].r_a0, "a0'", a0);
  567. TRC (r[1].r_a1, "a1'", a1);
  568. TRC (r[1].r_sb, "sb'", sb);
  569. TRC (r[1].r_fb, "fb'", fb);
  570. TRC (r_intbh, "intbh", intbh);
  571. TRC (r_intbl, "intbl", intbl);
  572. TRC (r_usp, "usp", usp);
  573. TRC (r_isp, "isp", isp);
  574. TRC (r_pc, "pc", pc);
  575. if (oldregs.r_flags != regs.r_flags)
  576. {
  577. printf (" flags ");
  578. print_flags (oldregs.r_flags);
  579. printf (":");
  580. print_flags (regs.r_flags);
  581. }
  582. printf ("\033[0m\n");
  583. }
  584. #define DRC(f, n, id) \
  585. printf(" %-3s %0*x", n, \
  586. reg_bytes[id]*2, (unsigned int)regs.f); \
  587. void
  588. m32c_dump_all_registers (void)
  589. {
  590. printf ("\033[36mREGS:");
  591. DRC (r[0].r_r0, "r0", r0);
  592. DRC (r[0].r_r1, "r1", r1);
  593. DRC (r[0].r_r2, "r2", r2);
  594. DRC (r[0].r_r3, "r3", r3);
  595. DRC (r[0].r_a0, "a0", a0);
  596. DRC (r[0].r_a1, "a1", a1);
  597. DRC (r[0].r_sb, "sb", sb);
  598. DRC (r[0].r_fb, "fb", fb);
  599. printf ("\n ");
  600. DRC (r[1].r_r0, "r0'", r0);
  601. DRC (r[1].r_r1, "r1'", r1);
  602. DRC (r[1].r_r2, "r2'", r2);
  603. DRC (r[1].r_r3, "r3'", r3);
  604. DRC (r[1].r_a0, "a0'", a0);
  605. DRC (r[1].r_a1, "a1'", a1);
  606. DRC (r[1].r_sb, "sb'", sb);
  607. DRC (r[1].r_fb, "fb'", fb);
  608. printf (" \n");
  609. DRC (r_intbh, "intbh", intbh);
  610. DRC (r_intbl, "intbl", intbl);
  611. DRC (r_usp, "usp", usp);
  612. DRC (r_isp, "isp", isp);
  613. DRC (r_pc, "pc", pc);
  614. printf (" flags ");
  615. print_flags (regs.r_flags);
  616. printf ("\033[0m\n");
  617. /*sim_disasm_one (); */
  618. }