sh64.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155
  1. /* SH5 simulator support code
  2. Copyright (C) 2000-2015 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. #define WANT_CPU
  16. #define WANT_CPU_SH64
  17. #include "sim-main.h"
  18. #include "sim-fpu.h"
  19. #include "cgen-mem.h"
  20. #include "cgen-ops.h"
  21. #include "gdb/callback.h"
  22. #include "defs-compact.h"
  23. #include "bfd.h"
  24. /* From include/gdb/. */
  25. #include "gdb/sim-sh.h"
  26. #define SYS_exit 1
  27. #define SYS_read 3
  28. #define SYS_write 4
  29. #define SYS_open 5
  30. #define SYS_close 6
  31. #define SYS_lseek 19
  32. #define SYS_time 23
  33. #define SYS_argc 172
  34. #define SYS_argnlen 173
  35. #define SYS_argn 174
  36. IDESC * sh64_idesc_media;
  37. IDESC * sh64_idesc_compact;
  38. BI
  39. sh64_endian (SIM_CPU *current_cpu)
  40. {
  41. return (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN);
  42. }
  43. SF
  44. sh64_fldi0 (SIM_CPU *current_cpu)
  45. {
  46. SF result;
  47. sim_fpu_to32 (&result, &sim_fpu_zero);
  48. return result;
  49. }
  50. SF
  51. sh64_fldi1 (SIM_CPU *current_cpu)
  52. {
  53. SF result;
  54. sim_fpu_to32 (&result, &sim_fpu_one);
  55. return result;
  56. }
  57. DF
  58. sh64_fabsd(SIM_CPU *current_cpu, DF drgh)
  59. {
  60. DF result;
  61. sim_fpu f, fres;
  62. sim_fpu_64to (&f, drgh);
  63. sim_fpu_abs (&fres, &f);
  64. sim_fpu_to64 (&result, &fres);
  65. return result;
  66. }
  67. SF
  68. sh64_fabss(SIM_CPU *current_cpu, SF frgh)
  69. {
  70. SF result;
  71. sim_fpu f, fres;
  72. sim_fpu_32to (&f, frgh);
  73. sim_fpu_abs (&fres, &f);
  74. sim_fpu_to32 (&result, &fres);
  75. return result;
  76. }
  77. DF
  78. sh64_faddd(SIM_CPU *current_cpu, DF drg, DF drh)
  79. {
  80. DF result;
  81. sim_fpu f1, f2, fres;
  82. sim_fpu_64to (&f1, drg);
  83. sim_fpu_64to (&f2, drh);
  84. sim_fpu_add (&fres, &f1, &f2);
  85. sim_fpu_to64 (&result, &fres);
  86. return result;
  87. }
  88. SF
  89. sh64_fadds(SIM_CPU *current_cpu, SF frg, SF frh)
  90. {
  91. SF result;
  92. sim_fpu f1, f2, fres;
  93. sim_fpu_32to (&f1, frg);
  94. sim_fpu_32to (&f2, frh);
  95. sim_fpu_add (&fres, &f1, &f2);
  96. sim_fpu_to32 (&result, &fres);
  97. return result;
  98. }
  99. BI
  100. sh64_fcmpeqd(SIM_CPU *current_cpu, DF drg, DF drh)
  101. {
  102. sim_fpu f1, f2;
  103. sim_fpu_64to (&f1, drg);
  104. sim_fpu_64to (&f2, drh);
  105. return sim_fpu_is_eq (&f1, &f2);
  106. }
  107. BI
  108. sh64_fcmpeqs(SIM_CPU *current_cpu, SF frg, SF frh)
  109. {
  110. sim_fpu f1, f2;
  111. sim_fpu_32to (&f1, frg);
  112. sim_fpu_32to (&f2, frh);
  113. return sim_fpu_is_eq (&f1, &f2);
  114. }
  115. BI
  116. sh64_fcmpged(SIM_CPU *current_cpu, DF drg, DF drh)
  117. {
  118. sim_fpu f1, f2;
  119. sim_fpu_64to (&f1, drg);
  120. sim_fpu_64to (&f2, drh);
  121. return sim_fpu_is_ge (&f1, &f2);
  122. }
  123. BI
  124. sh64_fcmpges(SIM_CPU *current_cpu, SF frg, SF frh)
  125. {
  126. sim_fpu f1, f2;
  127. sim_fpu_32to (&f1, frg);
  128. sim_fpu_32to (&f2, frh);
  129. return sim_fpu_is_ge (&f1, &f2);
  130. }
  131. BI
  132. sh64_fcmpgtd(SIM_CPU *current_cpu, DF drg, DF drh)
  133. {
  134. sim_fpu f1, f2;
  135. sim_fpu_64to (&f1, drg);
  136. sim_fpu_64to (&f2, drh);
  137. return sim_fpu_is_gt (&f1, &f2);
  138. }
  139. BI
  140. sh64_fcmpgts(SIM_CPU *current_cpu, SF frg, SF frh)
  141. {
  142. sim_fpu f1, f2;
  143. sim_fpu_32to (&f1, frg);
  144. sim_fpu_32to (&f2, frh);
  145. return sim_fpu_is_gt (&f1, &f2);
  146. }
  147. BI
  148. sh64_fcmpund(SIM_CPU *current_cpu, DF drg, DF drh)
  149. {
  150. sim_fpu f1, f2;
  151. sim_fpu_64to (&f1, drg);
  152. sim_fpu_64to (&f2, drh);
  153. return (sim_fpu_is_nan (&f1) || sim_fpu_is_nan (&f2));
  154. }
  155. BI
  156. sh64_fcmpuns(SIM_CPU *current_cpu, SF frg, SF frh)
  157. {
  158. sim_fpu f1, f2;
  159. sim_fpu_32to (&f1, frg);
  160. sim_fpu_32to (&f2, frh);
  161. return (sim_fpu_is_nan (&f1) || sim_fpu_is_nan (&f2));
  162. }
  163. SF
  164. sh64_fcnvds(SIM_CPU *current_cpu, DF drgh)
  165. {
  166. union {
  167. unsigned long long ll;
  168. double d;
  169. } f1;
  170. union {
  171. unsigned long l;
  172. float f;
  173. } f2;
  174. f1.ll = drgh;
  175. f2.f = (float) f1.d;
  176. return (SF) f2.l;
  177. }
  178. DF
  179. sh64_fcnvsd(SIM_CPU *current_cpu, SF frgh)
  180. {
  181. DF result;
  182. sim_fpu f;
  183. sim_fpu_32to (&f, frgh);
  184. sim_fpu_to64 (&result, &f);
  185. return result;
  186. }
  187. DF
  188. sh64_fdivd(SIM_CPU *current_cpu, DF drg, DF drh)
  189. {
  190. DF result;
  191. sim_fpu f1, f2, fres;
  192. sim_fpu_64to (&f1, drg);
  193. sim_fpu_64to (&f2, drh);
  194. sim_fpu_div (&fres, &f1, &f2);
  195. sim_fpu_to64 (&result, &fres);
  196. return result;
  197. }
  198. SF
  199. sh64_fdivs(SIM_CPU *current_cpu, SF frg, SF frh)
  200. {
  201. SF result;
  202. sim_fpu f1, f2, fres;
  203. sim_fpu_32to (&f1, frg);
  204. sim_fpu_32to (&f2, frh);
  205. sim_fpu_div (&fres, &f1, &f2);
  206. sim_fpu_to32 (&result, &fres);
  207. return result;
  208. }
  209. DF
  210. sh64_floatld(SIM_CPU *current_cpu, SF frgh)
  211. {
  212. DF result;
  213. sim_fpu f;
  214. sim_fpu_i32to (&f, frgh, sim_fpu_round_default);
  215. sim_fpu_to64 (&result, &f);
  216. return result;
  217. }
  218. SF
  219. sh64_floatls(SIM_CPU *current_cpu, SF frgh)
  220. {
  221. SF result;
  222. sim_fpu f;
  223. sim_fpu_i32to (&f, frgh, sim_fpu_round_default);
  224. sim_fpu_to32 (&result, &f);
  225. return result;
  226. }
  227. DF
  228. sh64_floatqd(SIM_CPU *current_cpu, DF drgh)
  229. {
  230. DF result;
  231. sim_fpu f;
  232. sim_fpu_i64to (&f, drgh, sim_fpu_round_default);
  233. sim_fpu_to64 (&result, &f);
  234. return result;
  235. }
  236. SF
  237. sh64_floatqs(SIM_CPU *current_cpu, DF drgh)
  238. {
  239. SF result;
  240. sim_fpu f;
  241. sim_fpu_i64to (&f, drgh, sim_fpu_round_default);
  242. sim_fpu_to32 (&result, &f);
  243. return result;
  244. }
  245. SF
  246. sh64_fmacs(SIM_CPU *current_cpu, SF fr0, SF frm, SF frn)
  247. {
  248. SF result;
  249. sim_fpu m1, m2, a1, fres;
  250. sim_fpu_32to (&m1, fr0);
  251. sim_fpu_32to (&m2, frm);
  252. sim_fpu_32to (&a1, frn);
  253. sim_fpu_mul (&fres, &m1, &m2);
  254. sim_fpu_add (&fres, &fres, &a1);
  255. sim_fpu_to32 (&result, &fres);
  256. return result;
  257. }
  258. DF
  259. sh64_fmuld(SIM_CPU *current_cpu, DF drg, DF drh)
  260. {
  261. DF result;
  262. sim_fpu f1, f2, fres;
  263. sim_fpu_64to (&f1, drg);
  264. sim_fpu_64to (&f2, drh);
  265. sim_fpu_mul (&fres, &f1, &f2);
  266. sim_fpu_to64 (&result, &fres);
  267. return result;
  268. }
  269. SF
  270. sh64_fmuls(SIM_CPU *current_cpu, SF frg, SF frh)
  271. {
  272. SF result;
  273. sim_fpu f1, f2, fres;
  274. sim_fpu_32to (&f1, frg);
  275. sim_fpu_32to (&f2, frh);
  276. sim_fpu_mul (&fres, &f1, &f2);
  277. sim_fpu_to32 (&result, &fres);
  278. return result;
  279. }
  280. DF
  281. sh64_fnegd(SIM_CPU *current_cpu, DF drgh)
  282. {
  283. DF result;
  284. sim_fpu f1, f2;
  285. sim_fpu_64to (&f1, drgh);
  286. sim_fpu_neg (&f2, &f1);
  287. sim_fpu_to64 (&result, &f2);
  288. return result;
  289. }
  290. SF
  291. sh64_fnegs(SIM_CPU *current_cpu, SF frgh)
  292. {
  293. SF result;
  294. sim_fpu f, fres;
  295. sim_fpu_32to (&f, frgh);
  296. sim_fpu_neg (&fres, &f);
  297. sim_fpu_to32 (&result, &fres);
  298. return result;
  299. }
  300. DF
  301. sh64_fsqrtd(SIM_CPU *current_cpu, DF drgh)
  302. {
  303. DF result;
  304. sim_fpu f, fres;
  305. sim_fpu_64to (&f, drgh);
  306. sim_fpu_sqrt (&fres, &f);
  307. sim_fpu_to64 (&result, &fres);
  308. return result;
  309. }
  310. SF
  311. sh64_fsqrts(SIM_CPU *current_cpu, SF frgh)
  312. {
  313. SF result;
  314. sim_fpu f, fres;
  315. sim_fpu_32to (&f, frgh);
  316. sim_fpu_sqrt (&fres, &f);
  317. sim_fpu_to32 (&result, &fres);
  318. return result;
  319. }
  320. DF
  321. sh64_fsubd(SIM_CPU *current_cpu, DF drg, DF drh)
  322. {
  323. DF result;
  324. sim_fpu f1, f2, fres;
  325. sim_fpu_64to (&f1, drg);
  326. sim_fpu_64to (&f2, drh);
  327. sim_fpu_sub (&fres, &f1, &f2);
  328. sim_fpu_to64 (&result, &fres);
  329. return result;
  330. }
  331. SF
  332. sh64_fsubs(SIM_CPU *current_cpu, SF frg, SF frh)
  333. {
  334. SF result;
  335. sim_fpu f1, f2, fres;
  336. sim_fpu_32to (&f1, frg);
  337. sim_fpu_32to (&f2, frh);
  338. sim_fpu_sub (&fres, &f1, &f2);
  339. sim_fpu_to32 (&result, &fres);
  340. return result;
  341. }
  342. SF
  343. sh64_ftrcdl(SIM_CPU *current_cpu, DF drgh)
  344. {
  345. SI result;
  346. sim_fpu f;
  347. sim_fpu_64to (&f, drgh);
  348. sim_fpu_to32i (&result, &f, sim_fpu_round_zero);
  349. return (SF) result;
  350. }
  351. SF
  352. sh64_ftrcsl(SIM_CPU *current_cpu, SF frgh)
  353. {
  354. SI result;
  355. sim_fpu f;
  356. sim_fpu_32to (&f, frgh);
  357. sim_fpu_to32i (&result, &f, sim_fpu_round_zero);
  358. return (SF) result;
  359. }
  360. DF
  361. sh64_ftrcdq(SIM_CPU *current_cpu, DF drgh)
  362. {
  363. DI result;
  364. sim_fpu f;
  365. sim_fpu_64to (&f, drgh);
  366. sim_fpu_to64i (&result, &f, sim_fpu_round_zero);
  367. return (DF) result;
  368. }
  369. DF
  370. sh64_ftrcsq(SIM_CPU *current_cpu, SF frgh)
  371. {
  372. DI result;
  373. sim_fpu f;
  374. sim_fpu_32to (&f, frgh);
  375. sim_fpu_to64i (&result, &f, sim_fpu_round_zero);
  376. return (DF) result;
  377. }
  378. VOID
  379. sh64_ftrvs(SIM_CPU *cpu, unsigned g, unsigned h, unsigned f)
  380. {
  381. int i, j;
  382. for (i = 0; i < 4; i++)
  383. {
  384. SF result;
  385. sim_fpu sum;
  386. sim_fpu_32to (&sum, 0);
  387. for (j = 0; j < 4; j++)
  388. {
  389. sim_fpu f1, f2, temp;
  390. sim_fpu_32to (&f1, sh64_h_fr_get (cpu, (g + i) + (j * 4)));
  391. sim_fpu_32to (&f2, sh64_h_fr_get (cpu, h + j));
  392. sim_fpu_mul (&temp, &f1, &f2);
  393. sim_fpu_add (&sum, &sum, &temp);
  394. }
  395. sim_fpu_to32 (&result, &sum);
  396. sh64_h_fr_set (cpu, f + i, result);
  397. }
  398. }
  399. VOID
  400. sh64_fipr (SIM_CPU *cpu, unsigned m, unsigned n)
  401. {
  402. SF result = sh64_fmuls (cpu, sh64_h_fvc_get (cpu, m), sh64_h_fvc_get (cpu, n));
  403. result = sh64_fadds (cpu, result, sh64_fmuls (cpu, sh64_h_frc_get (cpu, m + 1), sh64_h_frc_get (cpu, n + 1)));
  404. result = sh64_fadds (cpu, result, sh64_fmuls (cpu, sh64_h_frc_get (cpu, m + 2), sh64_h_frc_get (cpu, n + 2)));
  405. result = sh64_fadds (cpu, result, sh64_fmuls (cpu, sh64_h_frc_get (cpu, m + 3), sh64_h_frc_get (cpu, n + 3)));
  406. sh64_h_frc_set (cpu, n + 3, result);
  407. }
  408. SF
  409. sh64_fiprs (SIM_CPU *cpu, unsigned g, unsigned h)
  410. {
  411. SF temp = sh64_fmuls (cpu, sh64_h_fr_get (cpu, g), sh64_h_fr_get (cpu, h));
  412. temp = sh64_fadds (cpu, temp, sh64_fmuls (cpu, sh64_h_fr_get (cpu, g + 1), sh64_h_fr_get (cpu, h + 1)));
  413. temp = sh64_fadds (cpu, temp, sh64_fmuls (cpu, sh64_h_fr_get (cpu, g + 2), sh64_h_fr_get (cpu, h + 2)));
  414. temp = sh64_fadds (cpu, temp, sh64_fmuls (cpu, sh64_h_fr_get (cpu, g + 3), sh64_h_fr_get (cpu, h + 3)));
  415. return temp;
  416. }
  417. VOID
  418. sh64_fldp (SIM_CPU *cpu, PCADDR pc, DI rm, DI rn, unsigned f)
  419. {
  420. sh64_h_fr_set (cpu, f, GETMEMSF (cpu, pc, rm + rn));
  421. sh64_h_fr_set (cpu, f + 1, GETMEMSF (cpu, pc, rm + rn + 4));
  422. }
  423. VOID
  424. sh64_fstp (SIM_CPU *cpu, PCADDR pc, DI rm, DI rn, unsigned f)
  425. {
  426. SETMEMSF (cpu, pc, rm + rn, sh64_h_fr_get (cpu, f));
  427. SETMEMSF (cpu, pc, rm + rn + 4, sh64_h_fr_get (cpu, f + 1));
  428. }
  429. VOID
  430. sh64_ftrv (SIM_CPU *cpu, UINT ignored)
  431. {
  432. /* TODO: Unimplemented. */
  433. }
  434. VOID
  435. sh64_pref (SIM_CPU *cpu, SI addr)
  436. {
  437. /* TODO: Unimplemented. */
  438. }
  439. /* Count the number of arguments. */
  440. static int
  441. count_argc (cpu)
  442. SIM_CPU *cpu;
  443. {
  444. int i = 0;
  445. if (! STATE_PROG_ARGV (CPU_STATE (cpu)))
  446. return -1;
  447. while (STATE_PROG_ARGV (CPU_STATE (cpu)) [i] != NULL)
  448. ++i;
  449. return i;
  450. }
  451. /* Read a null terminated string from memory, return in a buffer */
  452. static char *
  453. fetch_str (current_cpu, pc, addr)
  454. SIM_CPU *current_cpu;
  455. PCADDR pc;
  456. DI addr;
  457. {
  458. char *buf;
  459. int nr = 0;
  460. while (sim_core_read_1 (current_cpu,
  461. pc, read_map, addr + nr) != 0)
  462. nr++;
  463. buf = NZALLOC (char, nr + 1);
  464. sim_read (CPU_STATE (current_cpu), addr, buf, nr);
  465. return buf;
  466. }
  467. static void
  468. trap_handler (SIM_CPU *current_cpu, int shmedia_abi_p, UQI trapnum, PCADDR pc)
  469. {
  470. char ch;
  471. switch (trapnum)
  472. {
  473. case 1:
  474. ch = GET_H_GRC (0);
  475. sim_io_write_stdout (CPU_STATE (current_cpu), &ch, 1);
  476. fflush (stdout);
  477. break;
  478. case 2:
  479. sim_engine_halt (CPU_STATE (current_cpu), current_cpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
  480. break;
  481. case 34:
  482. {
  483. int i;
  484. int ret_reg = (shmedia_abi_p) ? 2 : 0;
  485. char *buf;
  486. DI PARM1 = GET_H_GR ((shmedia_abi_p) ? 3 : 5);
  487. DI PARM2 = GET_H_GR ((shmedia_abi_p) ? 4 : 6);
  488. DI PARM3 = GET_H_GR ((shmedia_abi_p) ? 5 : 7);
  489. switch (GET_H_GR ((shmedia_abi_p) ? 2 : 4))
  490. {
  491. case SYS_write:
  492. buf = zalloc (PARM3);
  493. sim_read (CPU_STATE (current_cpu), PARM2, buf, PARM3);
  494. SET_H_GR (ret_reg,
  495. sim_io_write (CPU_STATE (current_cpu),
  496. PARM1, buf, PARM3));
  497. free (buf);
  498. break;
  499. case SYS_lseek:
  500. SET_H_GR (ret_reg,
  501. sim_io_lseek (CPU_STATE (current_cpu),
  502. PARM1, PARM2, PARM3));
  503. break;
  504. case SYS_exit:
  505. sim_engine_halt (CPU_STATE (current_cpu), current_cpu,
  506. NULL, pc, sim_exited, PARM1);
  507. break;
  508. case SYS_read:
  509. buf = zalloc (PARM3);
  510. SET_H_GR (ret_reg,
  511. sim_io_read (CPU_STATE (current_cpu),
  512. PARM1, buf, PARM3));
  513. sim_write (CPU_STATE (current_cpu), PARM2, buf, PARM3);
  514. free (buf);
  515. break;
  516. case SYS_open:
  517. buf = fetch_str (current_cpu, pc, PARM1);
  518. SET_H_GR (ret_reg,
  519. sim_io_open (CPU_STATE (current_cpu),
  520. buf, PARM2));
  521. free (buf);
  522. break;
  523. case SYS_close:
  524. SET_H_GR (ret_reg,
  525. sim_io_close (CPU_STATE (current_cpu), PARM1));
  526. break;
  527. case SYS_time:
  528. SET_H_GR (ret_reg, time (0));
  529. break;
  530. case SYS_argc:
  531. SET_H_GR (ret_reg, count_argc (current_cpu));
  532. break;
  533. case SYS_argnlen:
  534. if (PARM1 < count_argc (current_cpu))
  535. SET_H_GR (ret_reg,
  536. strlen (STATE_PROG_ARGV (CPU_STATE (current_cpu)) [PARM1]));
  537. else
  538. SET_H_GR (ret_reg, -1);
  539. break;
  540. case SYS_argn:
  541. if (PARM1 < count_argc (current_cpu))
  542. {
  543. /* Include the NULL byte. */
  544. i = strlen (STATE_PROG_ARGV (CPU_STATE (current_cpu)) [PARM1]) + 1;
  545. sim_write (CPU_STATE (current_cpu),
  546. PARM2,
  547. STATE_PROG_ARGV (CPU_STATE (current_cpu)) [PARM1],
  548. i);
  549. /* Just for good measure. */
  550. SET_H_GR (ret_reg, i);
  551. break;
  552. }
  553. else
  554. SET_H_GR (ret_reg, -1);
  555. break;
  556. default:
  557. SET_H_GR (ret_reg, -1);
  558. }
  559. }
  560. break;
  561. case 253:
  562. puts ("pass");
  563. exit (0);
  564. case 254:
  565. puts ("fail");
  566. exit (1);
  567. case 0xc3:
  568. /* fall through. */
  569. case 255:
  570. sim_engine_halt (CPU_STATE (current_cpu), current_cpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
  571. break;
  572. }
  573. }
  574. void
  575. sh64_trapa (SIM_CPU *current_cpu, DI rm, PCADDR pc)
  576. {
  577. trap_handler (current_cpu, 1, (UQI) rm & 0xff, pc);
  578. }
  579. void
  580. sh64_compact_trapa (SIM_CPU *current_cpu, UQI trapnum, PCADDR pc)
  581. {
  582. int mach_sh5_p;
  583. /* If this is an SH5 executable, this is SHcompact code running in
  584. the SHmedia ABI. */
  585. mach_sh5_p =
  586. (bfd_get_mach (STATE_PROG_BFD (CPU_STATE (current_cpu))) == bfd_mach_sh5);
  587. trap_handler (current_cpu, mach_sh5_p, trapnum, pc);
  588. }
  589. DI
  590. sh64_nsb (SIM_CPU *current_cpu, DI rm)
  591. {
  592. int result = 0, count;
  593. UDI source = (UDI) rm;
  594. if ((source >> 63))
  595. source = ~source;
  596. source <<= 1;
  597. for (count = 32; count; count >>= 1)
  598. {
  599. UDI newval = source << count;
  600. if ((newval >> count) == source)
  601. {
  602. result |= count;
  603. source = newval;
  604. }
  605. }
  606. return result;
  607. }
  608. void
  609. sh64_break (SIM_CPU *current_cpu, PCADDR pc)
  610. {
  611. SIM_DESC sd = CPU_STATE (current_cpu);
  612. sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
  613. }
  614. SI
  615. sh64_movua (SIM_CPU *current_cpu, PCADDR pc, SI rn)
  616. {
  617. SI v;
  618. int i;
  619. /* Move the data one byte at a time to avoid alignment problems.
  620. Be aware of endianness. */
  621. v = 0;
  622. for (i = 0; i < 4; ++i)
  623. v = (v << 8) | (GETMEMQI (current_cpu, pc, rn + i) & 0xff);
  624. v = T2H_4 (v);
  625. return v;
  626. }
  627. void
  628. set_isa (SIM_CPU *current_cpu, int mode)
  629. {
  630. /* Do nothing. */
  631. }
  632. /* The semantic code invokes this for invalid (unrecognized) instructions. */
  633. SEM_PC
  634. sim_engine_invalid_insn (SIM_CPU *current_cpu, IADDR cia, SEM_PC vpc)
  635. {
  636. SIM_DESC sd = CPU_STATE (current_cpu);
  637. sim_engine_halt (sd, current_cpu, NULL, cia, sim_stopped, SIM_SIGILL);
  638. return vpc;
  639. }
  640. /* Process an address exception. */
  641. void
  642. sh64_core_signal (SIM_DESC sd, SIM_CPU *current_cpu, sim_cia cia,
  643. unsigned int map, int nr_bytes, address_word addr,
  644. transfer_type transfer, sim_core_signals sig)
  645. {
  646. sim_core_signal (sd, current_cpu, cia, map, nr_bytes, addr,
  647. transfer, sig);
  648. }
  649. /* Initialize cycle counting for an insn.
  650. FIRST_P is non-zero if this is the first insn in a set of parallel
  651. insns. */
  652. void
  653. sh64_compact_model_insn_before (SIM_CPU *cpu, int first_p)
  654. {
  655. /* Do nothing. */
  656. }
  657. void
  658. sh64_media_model_insn_before (SIM_CPU *cpu, int first_p)
  659. {
  660. /* Do nothing. */
  661. }
  662. /* Record the cycles computed for an insn.
  663. LAST_P is non-zero if this is the last insn in a set of parallel insns,
  664. and we update the total cycle count.
  665. CYCLES is the cycle count of the insn. */
  666. void
  667. sh64_compact_model_insn_after(SIM_CPU *cpu, int last_p, int cycles)
  668. {
  669. /* Do nothing. */
  670. }
  671. void
  672. sh64_media_model_insn_after(SIM_CPU *cpu, int last_p, int cycles)
  673. {
  674. /* Do nothing. */
  675. }
  676. int
  677. sh64_fetch_register (SIM_CPU *cpu, int nr, unsigned char *buf, int len)
  678. {
  679. /* Fetch general purpose registers. */
  680. if (nr >= SIM_SH64_R0_REGNUM
  681. && nr < (SIM_SH64_R0_REGNUM + SIM_SH64_NR_R_REGS)
  682. && len == 8)
  683. {
  684. *((unsigned64*) buf) =
  685. H2T_8 (sh64_h_gr_get (cpu, nr - SIM_SH64_R0_REGNUM));
  686. return len;
  687. }
  688. /* Fetch PC. */
  689. if (nr == SIM_SH64_PC_REGNUM && len == 8)
  690. {
  691. *((unsigned64*) buf) = H2T_8 (sh64_h_pc_get (cpu) | sh64_h_ism_get (cpu));
  692. return len;
  693. }
  694. /* Fetch status register (SR). */
  695. if (nr == SIM_SH64_SR_REGNUM && len == 8)
  696. {
  697. *((unsigned64*) buf) = H2T_8 (sh64_h_sr_get (cpu));
  698. return len;
  699. }
  700. /* Fetch saved status register (SSR) and PC (SPC). */
  701. if ((nr == SIM_SH64_SSR_REGNUM || nr == SIM_SH64_SPC_REGNUM)
  702. && len == 8)
  703. {
  704. *((unsigned64*) buf) = 0;
  705. return len;
  706. }
  707. /* Fetch target registers. */
  708. if (nr >= SIM_SH64_TR0_REGNUM
  709. && nr < (SIM_SH64_TR0_REGNUM + SIM_SH64_NR_TR_REGS)
  710. && len == 8)
  711. {
  712. *((unsigned64*) buf) =
  713. H2T_8 (sh64_h_tr_get (cpu, nr - SIM_SH64_TR0_REGNUM));
  714. return len;
  715. }
  716. /* Fetch floating point registers. */
  717. if (nr >= SIM_SH64_FR0_REGNUM
  718. && nr < (SIM_SH64_FR0_REGNUM + SIM_SH64_NR_FP_REGS)
  719. && len == 4)
  720. {
  721. *((unsigned32*) buf) =
  722. H2T_4 (sh64_h_fr_get (cpu, nr - SIM_SH64_FR0_REGNUM));
  723. return len;
  724. }
  725. /* We should never get here. */
  726. return 0;
  727. }
  728. int
  729. sh64_store_register (SIM_CPU *cpu, int nr, unsigned char *buf, int len)
  730. {
  731. /* Store general purpose registers. */
  732. if (nr >= SIM_SH64_R0_REGNUM
  733. && nr < (SIM_SH64_R0_REGNUM + SIM_SH64_NR_R_REGS)
  734. && len == 8)
  735. {
  736. sh64_h_gr_set (cpu, nr - SIM_SH64_R0_REGNUM, T2H_8 (*((unsigned64*)buf)));
  737. return len;
  738. }
  739. /* Store PC. */
  740. if (nr == SIM_SH64_PC_REGNUM && len == 8)
  741. {
  742. unsigned64 new_pc = T2H_8 (*((unsigned64*)buf));
  743. sh64_h_pc_set (cpu, new_pc);
  744. return len;
  745. }
  746. /* Store status register (SR). */
  747. if (nr == SIM_SH64_SR_REGNUM && len == 8)
  748. {
  749. sh64_h_sr_set (cpu, T2H_8 (*((unsigned64*)buf)));
  750. return len;
  751. }
  752. /* Store saved status register (SSR) and PC (SPC). */
  753. if (nr == SIM_SH64_SSR_REGNUM || nr == SIM_SH64_SPC_REGNUM)
  754. {
  755. /* Do nothing. */
  756. return len;
  757. }
  758. /* Store target registers. */
  759. if (nr >= SIM_SH64_TR0_REGNUM
  760. && nr < (SIM_SH64_TR0_REGNUM + SIM_SH64_NR_TR_REGS)
  761. && len == 8)
  762. {
  763. sh64_h_tr_set (cpu, nr - SIM_SH64_TR0_REGNUM, T2H_8 (*((unsigned64*)buf)));
  764. return len;
  765. }
  766. /* Store floating point registers. */
  767. if (nr >= SIM_SH64_FR0_REGNUM
  768. && nr < (SIM_SH64_FR0_REGNUM + SIM_SH64_NR_FP_REGS)
  769. && len == 4)
  770. {
  771. sh64_h_fr_set (cpu, nr - SIM_SH64_FR0_REGNUM, T2H_4 (*((unsigned32*)buf)));
  772. return len;
  773. }
  774. /* We should never get here. */
  775. return 0;
  776. }
  777. void
  778. sh64_engine_run_full(SIM_CPU *cpu)
  779. {
  780. if (sh64_h_ism_get (cpu) == ISM_MEDIA)
  781. {
  782. if (!sh64_idesc_media)
  783. {
  784. sh64_media_init_idesc_table (cpu);
  785. sh64_idesc_media = CPU_IDESC (cpu);
  786. }
  787. else
  788. CPU_IDESC (cpu) = sh64_idesc_media;
  789. sh64_media_engine_run_full (cpu);
  790. }
  791. else
  792. {
  793. if (!sh64_idesc_compact)
  794. {
  795. sh64_compact_init_idesc_table (cpu);
  796. sh64_idesc_compact = CPU_IDESC (cpu);
  797. }
  798. else
  799. CPU_IDESC (cpu) = sh64_idesc_compact;
  800. sh64_compact_engine_run_full (cpu);
  801. }
  802. }
  803. void
  804. sh64_engine_run_fast (SIM_CPU *cpu)
  805. {
  806. if (sh64_h_ism_get (cpu) == ISM_MEDIA)
  807. {
  808. if (!sh64_idesc_media)
  809. {
  810. sh64_media_init_idesc_table (cpu);
  811. sh64_idesc_media = CPU_IDESC (cpu);
  812. }
  813. else
  814. CPU_IDESC (cpu) = sh64_idesc_media;
  815. sh64_media_engine_run_fast (cpu);
  816. }
  817. else
  818. {
  819. if (!sh64_idesc_compact)
  820. {
  821. sh64_compact_init_idesc_table (cpu);
  822. sh64_idesc_compact = CPU_IDESC (cpu);
  823. }
  824. else
  825. CPU_IDESC (cpu) = sh64_idesc_compact;
  826. sh64_compact_engine_run_fast (cpu);
  827. }
  828. }
  829. static void
  830. sh64_prepare_run (SIM_CPU *cpu)
  831. {
  832. /* Nothing. */
  833. }
  834. static const CGEN_INSN *
  835. sh64_get_idata (SIM_CPU *cpu, int inum)
  836. {
  837. return CPU_IDESC (cpu) [inum].idata;
  838. }
  839. static void
  840. sh64_init_cpu (SIM_CPU *cpu)
  841. {
  842. CPU_REG_FETCH (cpu) = sh64_fetch_register;
  843. CPU_REG_STORE (cpu) = sh64_store_register;
  844. CPU_PC_FETCH (cpu) = sh64_h_pc_get;
  845. CPU_PC_STORE (cpu) = sh64_h_pc_set;
  846. CPU_GET_IDATA (cpu) = sh64_get_idata;
  847. /* Only used by profiling. 0 disables it. */
  848. CPU_MAX_INSNS (cpu) = 0;
  849. CPU_INSN_NAME (cpu) = cgen_insn_name;
  850. CPU_FULL_ENGINE_FN (cpu) = sh64_engine_run_full;
  851. #if WITH_FAST
  852. CPU_FAST_ENGINE_FN (cpu) = sh64_engine_run_fast;
  853. #else
  854. CPU_FAST_ENGINE_FN (cpu) = sh64_engine_run_full;
  855. #endif
  856. }
  857. static void
  858. shmedia_init_cpu (SIM_CPU *cpu)
  859. {
  860. sh64_init_cpu (cpu);
  861. }
  862. static void
  863. shcompact_init_cpu (SIM_CPU *cpu)
  864. {
  865. sh64_init_cpu (cpu);
  866. }
  867. static void
  868. sh64_model_init()
  869. {
  870. /* Do nothing. */
  871. }
  872. static const MODEL sh_models [] =
  873. {
  874. { "sh2", & sh2_mach, MODEL_SH5, NULL, sh64_model_init },
  875. { "sh2e", & sh2e_mach, MODEL_SH5, NULL, sh64_model_init },
  876. { "sh2a", & sh2a_fpu_mach, MODEL_SH5, NULL, sh64_model_init },
  877. { "sh2a_nofpu", & sh2a_nofpu_mach, MODEL_SH5, NULL, sh64_model_init },
  878. { "sh3", & sh3_mach, MODEL_SH5, NULL, sh64_model_init },
  879. { "sh3e", & sh3_mach, MODEL_SH5, NULL, sh64_model_init },
  880. { "sh4", & sh4_mach, MODEL_SH5, NULL, sh64_model_init },
  881. { "sh4_nofpu", & sh4_nofpu_mach, MODEL_SH5, NULL, sh64_model_init },
  882. { "sh4a", & sh4a_mach, MODEL_SH5, NULL, sh64_model_init },
  883. { "sh4a_nofpu", & sh4a_nofpu_mach, MODEL_SH5, NULL, sh64_model_init },
  884. { "sh4al", & sh4al_mach, MODEL_SH5, NULL, sh64_model_init },
  885. { "sh5", & sh5_mach, MODEL_SH5, NULL, sh64_model_init },
  886. { 0 }
  887. };
  888. static const MACH_IMP_PROPERTIES sh5_imp_properties =
  889. {
  890. sizeof (SIM_CPU),
  891. #if WITH_SCACHE
  892. sizeof (SCACHE)
  893. #else
  894. 0
  895. #endif
  896. };
  897. const MACH sh2_mach =
  898. {
  899. "sh2", "sh2", MACH_SH5,
  900. 16, 16, &sh_models[0], &sh5_imp_properties,
  901. shcompact_init_cpu,
  902. sh64_prepare_run
  903. };
  904. const MACH sh2e_mach =
  905. {
  906. "sh2e", "sh2e", MACH_SH5,
  907. 16, 16, &sh_models[1], &sh5_imp_properties,
  908. shcompact_init_cpu,
  909. sh64_prepare_run
  910. };
  911. const MACH sh2a_fpu_mach =
  912. {
  913. "sh2a", "sh2a", MACH_SH5,
  914. 16, 16, &sh_models[2], &sh5_imp_properties,
  915. shcompact_init_cpu,
  916. sh64_prepare_run
  917. };
  918. const MACH sh2a_nofpu_mach =
  919. {
  920. "sh2a_nofpu", "sh2a_nofpu", MACH_SH5,
  921. 16, 16, &sh_models[3], &sh5_imp_properties,
  922. shcompact_init_cpu,
  923. sh64_prepare_run
  924. };
  925. const MACH sh3_mach =
  926. {
  927. "sh3", "sh3", MACH_SH5,
  928. 16, 16, &sh_models[4], &sh5_imp_properties,
  929. shcompact_init_cpu,
  930. sh64_prepare_run
  931. };
  932. const MACH sh3e_mach =
  933. {
  934. "sh3e", "sh3e", MACH_SH5,
  935. 16, 16, &sh_models[5], &sh5_imp_properties,
  936. shcompact_init_cpu,
  937. sh64_prepare_run
  938. };
  939. const MACH sh4_mach =
  940. {
  941. "sh4", "sh4", MACH_SH5,
  942. 16, 16, &sh_models[6], &sh5_imp_properties,
  943. shcompact_init_cpu,
  944. sh64_prepare_run
  945. };
  946. const MACH sh4_nofpu_mach =
  947. {
  948. "sh4_nofpu", "sh4_nofpu", MACH_SH5,
  949. 16, 16, &sh_models[7], &sh5_imp_properties,
  950. shcompact_init_cpu,
  951. sh64_prepare_run
  952. };
  953. const MACH sh4a_mach =
  954. {
  955. "sh4a", "sh4a", MACH_SH5,
  956. 16, 16, &sh_models[8], &sh5_imp_properties,
  957. shcompact_init_cpu,
  958. sh64_prepare_run
  959. };
  960. const MACH sh4a_nofpu_mach =
  961. {
  962. "sh4a_nofpu", "sh4a_nofpu", MACH_SH5,
  963. 16, 16, &sh_models[9], &sh5_imp_properties,
  964. shcompact_init_cpu,
  965. sh64_prepare_run
  966. };
  967. const MACH sh4al_mach =
  968. {
  969. "sh4al", "sh4al", MACH_SH5,
  970. 16, 16, &sh_models[10], &sh5_imp_properties,
  971. shcompact_init_cpu,
  972. sh64_prepare_run
  973. };
  974. const MACH sh5_mach =
  975. {
  976. "sh5", "sh5", MACH_SH5,
  977. 32, 32, &sh_models[11], &sh5_imp_properties,
  978. shmedia_init_cpu,
  979. sh64_prepare_run
  980. };