alphasim.pas 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282
  1. {
  2. $Id$
  3. This file is part of the Free Pascal simulator environment
  4. Copyright (c) 1999-2000 by Florian Klaempfl
  5. This file is the main file of the DEC Alpha simulation
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. {$N+}
  13. { $define DEBUG}
  14. program alphaemu;
  15. uses
  16. {$ifdef delphi}
  17. dmisc,
  18. {$else}
  19. dos,
  20. {$endif}
  21. simbase,simlib,
  22. {$ifdef FPC}
  23. {$ifdef go32v2}
  24. dpmiexcp,
  25. {$endif go32v2}
  26. {$endif FPC}
  27. {$ifdef TP}
  28. mm64
  29. {$else TP}
  30. {$define fastmem}
  31. fastmm64
  32. {$endif TP}
  33. ;
  34. { elf file types }
  35. type
  36. telf64_hdr = packed record
  37. e_ident : array[0..15] of char;
  38. e_type : integer;
  39. e_machine : word;
  40. version : longint;
  41. e_entry : qword;
  42. e_phoff : qword;
  43. e_shoff : qword;
  44. e_flags : longint;
  45. e_ehsize : integer;
  46. e_phentsize : integer;
  47. e_phnum : integer;
  48. e_shentsize : integer;
  49. e_shnum : integer;
  50. e_shstrndx : integer;
  51. end;
  52. telf64_phdr = packed record
  53. p_type : longint;
  54. p_flags : longint;
  55. { Segment file offset }
  56. p_offset : qword;
  57. { Segment virtual address }
  58. p_vaddr : qword;
  59. { Segment physical address }
  60. p_paddr : qword;
  61. { Segment size in file }
  62. p_filesz : qword;
  63. { Segment size in memory }
  64. p_memsz : qword;
  65. { Segment alignment, file & memory }
  66. p_align : qword;
  67. end;
  68. telf64_phdr_array = array[0..0] of telf64_phdr;
  69. pelf64_phdr_array = ^telf64_phdr_array;
  70. const
  71. {$ifdef fpc}
  72. { 64kB Stacksize }
  73. stacksize = 64*1024;
  74. { stack start at 4 GB }
  75. stackstart : dword = 1024*1024*1024*4-stacksize;
  76. {$else fpc}
  77. { 64kB Stacksize }
  78. stacksize = 64*1024.0;
  79. { stack start at 4 GB }
  80. stackstart = 1024.0*1024.0*1024.0*4-stacksize;
  81. {$endif fpc}
  82. { alpha specific types }
  83. type
  84. tintreg = record
  85. case tindex of
  86. 1 : (all64 : qword);
  87. 2 : (valueq : int64);
  88. 3 : (low32 : dword;high32 : dword);
  89. 4 : (bytes : array[0..7] of byte)
  90. end;
  91. tfloatreg = record
  92. case tindex of
  93. 1 : (valued : double);
  94. 2 : (valueq : qword);
  95. end;
  96. tinstruction = dword;
  97. tintregs = array[0..31] of tintreg;
  98. tfloatregs = array[0..31] of tfloatreg;
  99. tstate = object
  100. r : tintregs;
  101. f : tfloatregs;
  102. pc : taddr;
  103. fpcr : qword;
  104. end;
  105. const
  106. r_v0 = 0;
  107. r_t0 = 1;
  108. r_fp = 15;
  109. r_a0 = 16;
  110. r_a1 = 17;
  111. r_a2 = 18;
  112. r_a3 = 19;
  113. r_a4 = 20;
  114. r_a5 = 11;
  115. r_ra = 26;
  116. r_at = 28;
  117. r_gp = 29;
  118. r_sp = 30;
  119. r_zero = 31;
  120. f_zero = 31;
  121. type
  122. talphasim = object
  123. state : tstate;
  124. memory : tmemorymanager;
  125. { number of executed instructions }
  126. instrcount : qword;
  127. { time when the emulation was started }
  128. starttime : double;
  129. { starts the execution at address pc }
  130. procedure run(pc : taddr);
  131. { gives a message about an illegal opcode }
  132. { at the given address }
  133. procedure illegalopcode(addr : taddr);
  134. { dumps the contens of the register a0 to a[count] }
  135. procedure dumparguments(count : tindex);
  136. { dumps the contents of the function result register }
  137. procedure dumpv0;
  138. constructor init;
  139. destructor done;
  140. end;
  141. var
  142. sim : talphasim;
  143. procedure dump_phdr(const h : telf64_phdr);
  144. begin
  145. {$ifdef DEBUG}
  146. writeln(' Type: $',hexstr(h.p_type,8));
  147. writeln(' Flags: $',hexstr(h.p_flags,8));
  148. writeln(' Segment file offset: $',qword2str(h.p_offset));
  149. writeln(' Segment virtual address: $',qword2str(h.p_vaddr));
  150. writeln(' Segment physical address: $',qword2str(h.p_paddr));
  151. writeln(' Segment size in file: $',qword2str(h.p_filesz));
  152. writeln(' Segment size in memory: $',qword2str(h.p_memsz));
  153. writeln(' Segment alignment, file & memory: $',qword2str(h.p_align));
  154. {$endif DEBUG}
  155. end;
  156. procedure _stopsim;{$ifdef TP}far;{$endif TP}
  157. var
  158. elapsedtime : double;
  159. begin
  160. {$ifdef DEBUG}
  161. elapsedtime:=realtime-sim.starttime;
  162. write('Executed ',sim.instrcount:0,' instructions in ',
  163. elapsedtime:0:2,' sec');
  164. if elapsedtime<>0.0 then
  165. begin
  166. writeln(',');
  167. writeln('equals to ',sim.instrcount/(elapsedtime*1000000.0):0:4,' MIPS');
  168. end
  169. else
  170. writeln;
  171. {$endif DEBUG}
  172. halt(1);
  173. end;
  174. constructor talphasim.init;
  175. begin
  176. memory.init;
  177. { setup dummy registers }
  178. state.r[31].valueq:=0;
  179. state.f[31].valued:=0;
  180. memory.allocate(stackstart,stacksize);
  181. end;
  182. procedure talphasim.illegalopcode(addr : taddr);
  183. var
  184. instruction : tinstruction;
  185. begin
  186. instruction:=memory.readd(addr);
  187. writeln('Illegal instruction $',hexstr(instruction,8),' at $',qword2str(addr));
  188. writeln('Opcode is: $',hexstr((instruction and $fc000000) shr 26,2));
  189. writeln(' Function would be: $',hexstr((instruction and $1fe0) shr 5,3));
  190. writeln;
  191. stopsim;
  192. end;
  193. procedure talphasim.dumparguments(count : tindex);
  194. var
  195. i : tindex;
  196. begin
  197. if count>6 then
  198. begin
  199. writeln('Illegal number of arguments to print');
  200. halt(1);
  201. end;
  202. {$ifdef DEBUG}
  203. for i:=0 to count-1 do
  204. writeln(' Register a',i,' = $',qword2str(state.r[r_a0+i].valueq));
  205. {$endif DEBUG}
  206. end;
  207. procedure talphasim.dumpv0;
  208. var
  209. i : tindex;
  210. begin
  211. {$ifdef DEBUG}
  212. writeln(' Register v0 = $',qword2str(state.r[r_v0].valueq));
  213. {$endif DEBUG}
  214. end;
  215. procedure talphasim.run(pc : taddr);
  216. var
  217. instruction : tinstruction;
  218. rega,regb,regc : tindex;
  219. lit : byte;
  220. va : tintreg;
  221. function getbranchdisp : int64;
  222. var
  223. l : longint;
  224. begin
  225. l:=longint(instruction and $1fffff)*4;
  226. { sign extend }
  227. if (l and $100000)<>0 then
  228. l:=l or $fff00000;
  229. getbranchdisp:=l;
  230. end;
  231. procedure instructionignored(const s : string);
  232. begin
  233. {$ifdef DEBUG}
  234. writeln('Instruction "',s,'" at $',qword2str(instructionpc),' ignored');
  235. {$endif DEBUG}
  236. end;
  237. procedure syscallignored(const s : string);
  238. begin
  239. {$ifdef DEBUG}
  240. writeln('SYSCALL "',s,'" at $',qword2str(instructionpc),' ignored');
  241. {$endif DEBUG}
  242. end;
  243. procedure syscalldefault(const s : string);
  244. begin
  245. {$ifdef DEBUG}
  246. writeln('SYSCALL "',s,'" at $',qword2str(instructionpc),', default value returned');
  247. {$endif DEBUG}
  248. end;
  249. var
  250. i : tindex;
  251. fs : single;
  252. ib : byte;
  253. il : longint;
  254. fc : comp;
  255. ic : char;
  256. valueqa,valueqb : qword;
  257. oi : oword;
  258. count : qword;
  259. {$ifdef FASTMEM}
  260. block : pdword;
  261. fastpc : longint;
  262. updatepc : boolean;
  263. {$endif FASTMEM}
  264. begin
  265. instrcount:=0;
  266. state.pc:=pc;
  267. { setting up the stack pointer }
  268. state.r[r_sp].valueq:=stackstart+stacksize-24;
  269. { setting up command line parameters ... }
  270. state.r[r_a0].valueq:=0;
  271. state.r[r_a1].valueq:=0;
  272. { ... and environment }
  273. state.r[r_a2].valueq:=0;
  274. starttime:=realtime;
  275. {$ifdef FASTMEM}
  276. updatepc:=true;
  277. {$endif FASTMEM}
  278. repeat
  279. { read the next instruction }
  280. {$ifdef FASTMEM}
  281. if updatepc then
  282. begin
  283. block:=pdword(memory.mem[((tqwordrec(state.pc).high32 and $f) shl 12) or
  284. ((tqwordrec(state.pc).low32 and $fff) shr 20)]);
  285. fastpc:=(tqwordrec(state.pc).low32 and $fffff) shr 2;
  286. end;
  287. instruction:=block[fastpc];
  288. inc(fastpc);
  289. updatepc:=fastpc>1024*256-1;
  290. {$else FASTMEM}
  291. instruction:=memory.readalignedd(state.pc);
  292. {$endif FASTMEM}
  293. instructionpc:=state.pc;
  294. state.pc:=state.pc+4;
  295. { decode the instruction }
  296. case (instruction and $fc000000) shr 26 of
  297. { CALL_PAL }
  298. $0:
  299. begin
  300. case instruction and $3ffffff of
  301. { halt }
  302. 0:
  303. exit;
  304. 131:
  305. begin
  306. if state.r[r_v0].high32=0 then
  307. case state.r[r_v0].low32 of
  308. { Setup }
  309. 0:
  310. begin
  311. syscallignored('setup');
  312. { mimic proper execution }
  313. state.r[r_v0].valueq:=0;
  314. end;
  315. 1:
  316. begin
  317. exit;
  318. end;
  319. 4:
  320. begin
  321. syscallignored('write');
  322. state.r[r_v0].valueq:=0;
  323. count:=0;
  324. while count<state.r[r_a2].valueq do
  325. begin
  326. byte(ic):=memory.readb(state.r[r_a1].valueq+count);
  327. { all output goes currently to stdout }
  328. if ic=#10 then
  329. writeln(output)
  330. else
  331. write(output,ic);
  332. count:=count+1;
  333. state.r[r_v0].valueq:=state.r[r_v0].valueq+1;
  334. end;
  335. end;
  336. 20:
  337. begin
  338. syscalldefault('getpid');
  339. { return a default value }
  340. state.r[r_v0].valueq:=501;
  341. end;
  342. 24:
  343. begin
  344. syscalldefault('getuid');
  345. { return a default value }
  346. state.r[r_v0].valueq:=501;
  347. end;
  348. 45:
  349. begin
  350. syscallignored('brk');
  351. { mimic proper execution }
  352. state.r[r_v0].valueq:=0;
  353. end;
  354. { alpha specific }
  355. $100:
  356. begin
  357. syscallignored('osf_getsysinfo');
  358. { mimic proper execution }
  359. state.r[r_v0].valueq:=0;
  360. end;
  361. $101:
  362. begin
  363. syscallignored('osf_setsysinfo');
  364. { mimic proper execution }
  365. state.r[r_v0].valueq:=0;
  366. end;
  367. $144:
  368. begin
  369. syscallignored('personality');
  370. { mimic proper execution }
  371. state.r[r_v0].valueq:=0;
  372. end;
  373. else
  374. begin
  375. syscallignored('<Unknown>');
  376. dumpv0;
  377. dumparguments(4);
  378. end;
  379. end
  380. else
  381. begin
  382. syscallignored('<Unknown>');
  383. dumpv0;
  384. dumparguments(4);
  385. end;
  386. end;
  387. else
  388. writeln('PAL code $',hexstr(instruction and $3ffffff,8),' at $',
  389. qword2str(instructionpc),' ignored');
  390. end;
  391. end;
  392. { LDA }
  393. $8:
  394. begin
  395. rega:=(instruction and $3e00000) shr 21;
  396. regb:=(instruction and $1f0000) shr 16;
  397. if rega<>r_zero then
  398. state.r[rega].valueq:=state.r[regb].valueq+int64(integer(instruction and $ffff));
  399. end;
  400. { LDAH }
  401. $9:
  402. begin
  403. rega:=(instruction and $3e00000) shr 21;
  404. regb:=(instruction and $1f0000) shr 16;
  405. if rega<>r_zero then
  406. state.r[rega].valueq:=state.r[regb].valueq+
  407. (int64(integer(instruction and $ffff))*65536);
  408. end;
  409. { LDQ_U }
  410. $B:
  411. begin
  412. { !!!!! no MSB support yet! }
  413. rega:=(instruction and $3e00000) shr 21;
  414. regb:=(instruction and $1f0000) shr 16;
  415. valueqb:=state.r[regb].valueq+
  416. (int64(integer(instruction and $ffff)));
  417. tqwordrec(valueqb).low32:=tqwordrec(valueqb).low32 and $fffffff8;
  418. if rega<>r_zero then
  419. state.r[rega].valueq:=memory.readq(valueqb);
  420. end;
  421. { STQ_U }
  422. $f:
  423. begin
  424. { !!!!! no MSB support yet! }
  425. rega:=(instruction and $3e00000) shr 21;
  426. regb:=(instruction and $1f0000) shr 16;
  427. va.valueq:=state.r[regb].valueq+
  428. (int64(integer(instruction and $ffff)));
  429. memory.writeq(va.valueq,state.r[rega].valueq);
  430. end;
  431. { ************* opcode $10 ************** }
  432. $10:
  433. begin
  434. rega:=(instruction and $3e00000) shr 21;
  435. regb:=(instruction and $1f0000) shr 16;
  436. regc:=instruction and $1f;
  437. valueqa:=state.r[rega].valueq;
  438. if (instruction and $1000)<>0 then
  439. valueqb:=(instruction and $1fe000) shr 13
  440. else
  441. valueqb:=state.r[regb].valueq;
  442. case (instruction and $fe0) shr 5 of
  443. { ADDL }
  444. $0:
  445. begin
  446. if regc<>r_zero then
  447. state.r[regc].low32:=tqwordrec(valueqa).low32+tqwordrec(valueqb).low32;
  448. end;
  449. { CMPULT }
  450. $1D:
  451. begin
  452. if (regc<>r_zero) then
  453. state.r[regc].valueq:=byte(ltu(valueqa,valueqb));
  454. end;
  455. { ADDQ }
  456. $20:
  457. begin
  458. if regc<>r_zero then
  459. state.r[regc].valueq:=valueqa+valueqb;
  460. end;
  461. { S4ADDQ }
  462. $22:
  463. begin
  464. if regc<>r_zero then
  465. state.r[regc].valueq:=valueqa*4+valueqb;
  466. end;
  467. { SUBQ }
  468. $29:
  469. begin
  470. if regc<>r_zero then
  471. state.r[regc].valueq:=valueqa-valueqb;
  472. end;
  473. { S4SUBQ }
  474. $2B:
  475. begin
  476. if regc<>r_zero then
  477. state.r[regc].valueq:=valueqa*4-valueqb;
  478. end;
  479. { CMPEQ }
  480. $2D:
  481. begin
  482. if (regc<>r_zero) then
  483. state.r[regc].valueq:=byte(valueqa=valueqb);
  484. end;
  485. { S8ADDQ }
  486. $32:
  487. begin
  488. if regc<>r_zero then
  489. state.r[regc].valueq:=valueqa*8+valueqb;
  490. end;
  491. { S8SUBQ }
  492. $3B:
  493. begin
  494. if regc<>r_zero then
  495. state.r[regc].valueq:=valueqa*8-valueqb;
  496. end;
  497. { CMPULE }
  498. $3D:
  499. begin
  500. if (regc<>r_zero) then
  501. state.r[regc].valueq:=byte(leu(valueqa,valueqb));
  502. end;
  503. { CMPLT }
  504. $4D:
  505. begin
  506. if (regc<>r_zero) then
  507. state.r[regc].valueq:=byte(valueqa<valueqb);
  508. end;
  509. { CMPLE }
  510. $6D:
  511. begin
  512. if (regc<>r_zero) then
  513. state.r[regc].valueq:=byte(valueqa<=valueqb);
  514. end;
  515. else
  516. illegalopcode(instructionpc);
  517. end;
  518. end;
  519. { ************* opcode $11 ************** }
  520. $11:
  521. begin
  522. rega:=(instruction and $3e00000) shr 21;
  523. regb:=(instruction and $1f0000) shr 16;
  524. regc:=instruction and $1f;
  525. valueqa:=state.r[rega].valueq;
  526. if (instruction and $1000)<>0 then
  527. valueqb:=(instruction and $1fe000) shr 13
  528. else
  529. valueqb:=state.r[regb].valueq;
  530. case (instruction and $fe0) shr 5 of
  531. { AND }
  532. $00:
  533. begin
  534. if regc<>r_zero then
  535. begin
  536. state.r[regc].low32:=tqwordrec(valueqa).low32 and
  537. tqwordrec(valueqb).low32;
  538. state.r[regc].high32:=tqwordrec(valueqa).high32 and
  539. tqwordrec(valueqb).high32;
  540. end;
  541. end;
  542. { BIC }
  543. $08:
  544. begin
  545. if regc<>r_zero then
  546. begin
  547. state.r[regc].low32:=tqwordrec(valueqa).low32 and
  548. not(tqwordrec(valueqb).low32);
  549. state.r[regc].high32:=tqwordrec(valueqa).high32 and
  550. not(tqwordrec(valueqb).high32);
  551. end;
  552. end;
  553. { CMOVLBS }
  554. $14:
  555. begin
  556. if (regc<>r_zero) and ((tqwordrec(valueqa).low32 and 1)<>0) then
  557. state.r[regc].valueq:=valueqb;
  558. end;
  559. { CMOVLBC }
  560. $16:
  561. begin
  562. if (regc<>r_zero) and ((tqwordrec(valueqa).low32 and 1)=0) then
  563. state.r[regc].valueq:=valueqb;
  564. end;
  565. { BIS }
  566. $20:
  567. begin
  568. if regc<>r_zero then
  569. begin
  570. state.r[regc].low32:=tqwordrec(valueqa).low32 or
  571. tqwordrec(valueqb).low32;
  572. state.r[regc].high32:=tqwordrec(valueqa).high32 or
  573. tqwordrec(valueqb).high32;
  574. end;
  575. end;
  576. { CMOVEQ }
  577. $24:
  578. begin
  579. if (regc<>r_zero) and (valueqa=0) then
  580. state.r[regc].valueq:=valueqb;
  581. end;
  582. { CMOVNE }
  583. $26:
  584. begin
  585. if (regc<>r_zero) and (valueqa<>0) then
  586. state.r[regc].valueq:=valueqb;
  587. end;
  588. { ORNOT }
  589. $28:
  590. begin
  591. if regc<>r_zero then
  592. begin
  593. state.r[regc].low32:=tqwordrec(valueqa).low32 or
  594. not(tqwordrec(valueqb).low32);
  595. state.r[regc].high32:=tqwordrec(valueqa).high32 or
  596. not(tqwordrec(valueqb).high32);
  597. end;
  598. end;
  599. { XOR }
  600. $40:
  601. begin
  602. if regc<>r_zero then
  603. begin
  604. state.r[regc].valueq:=state.r[rega].valueq xor
  605. valueqb;
  606. end;
  607. end;
  608. { CMOVLT }
  609. $44:
  610. begin
  611. if (regc<>r_zero) and (valueqa<0) then
  612. state.r[regc].valueq:=valueqb;
  613. end;
  614. { CMOVGE }
  615. $46:
  616. begin
  617. if (regc<>r_zero) and (valueqa>=0) then
  618. state.r[regc].valueq:=valueqb;
  619. end;
  620. { EQV }
  621. $48:
  622. begin
  623. if regc<>r_zero then
  624. begin
  625. state.r[regc].valueq:=valueqa xor
  626. not(valueqb);
  627. end;
  628. end;
  629. { CMOVLE }
  630. $64:
  631. begin
  632. if (regc<>r_zero) and (valueqa<=0) then
  633. state.r[regc].valueq:=valueqb;
  634. end;
  635. { CMOVGT }
  636. $66:
  637. begin
  638. if (regc<>r_zero) and (valueqa<=0) then
  639. state.r[regc].valueq:=valueqb;
  640. end;
  641. else
  642. illegalopcode(instructionpc);
  643. end;
  644. end;
  645. { ************* opcode $12 ************** }
  646. $12:
  647. begin
  648. rega:=(instruction and $3e00000) shr 21;
  649. regb:=(instruction and $1f0000) shr 16;
  650. regc:=instruction and $1f;
  651. valueqa:=state.r[rega].valueq;
  652. if (instruction and $1000)<>0 then
  653. valueqb:=(instruction and $1fe000) shr 13
  654. else
  655. valueqb:=state.r[regb].valueq;
  656. case (instruction and $fe0) shr 5 of
  657. { MSKBL }
  658. $02:
  659. begin
  660. { !!!!! no MSB support yet! }
  661. il:=1 shl (tqwordrec(valueqb).low32 and $7);
  662. if (regc<>r_zero) then
  663. byte_zap(valueqa,il and $ff,state.r[regc].valueq);
  664. end;
  665. { EXTBL }
  666. $06:
  667. begin
  668. { !!!!! no MSB support yet! }
  669. shift_right_q(valueqa,(tqwordrec(valueqb).low32 and $7)*8,valueqa);
  670. if (regc<>r_zero) then
  671. byte_zap(valueqa,$fe,state.r[regc].valueq);
  672. end;
  673. { INSBL }
  674. $0B:
  675. begin
  676. { !!!!! no MSB support yet! }
  677. il:=1 shl (tqwordrec(valueqb).low32 and $7);
  678. shift_left_q(valueqa,(tqwordrec(valueqb).low32 and $7)*8,valueqa);
  679. if (regc<>r_zero) then
  680. byte_zap(valueqa,not(il and $ff),state.r[regc].valueq);
  681. end;
  682. { MSKWL }
  683. $12:
  684. begin
  685. { !!!!! no MSB support yet! }
  686. il:=3 shl (tqwordrec(valueqb).low32 and $7);
  687. if (regc<>r_zero) then
  688. byte_zap(valueqa,il and $ff,state.r[regc].valueq);
  689. end;
  690. { EXTWL }
  691. $16:
  692. begin
  693. { !!!!! no MSB support yet! }
  694. shift_right_q(valueqa,(tqwordrec(valueqb).low32 and $7)*8,valueqa);
  695. if (regc<>r_zero) then
  696. byte_zap(valueqa,$fc,state.r[regc].valueq);
  697. end;
  698. { MSKLL }
  699. $22:
  700. begin
  701. { !!!!! no MSB support yet! }
  702. il:=$f shl (tqwordrec(valueqb).low32 and $7);
  703. if (regc<>r_zero) then
  704. byte_zap(valueqa,il and $ff,state.r[regc].valueq);
  705. end;
  706. { EXTLL }
  707. $26:
  708. begin
  709. { !!!!! no MSB support yet! }
  710. shift_right_q(valueqa,(tqwordrec(valueqb).low32 and $7)*8,valueqa);
  711. if (regc<>r_zero) then
  712. byte_zap(valueqa,$f0,state.r[regc].valueq);
  713. end;
  714. { ZAP }
  715. $30:
  716. begin
  717. if regc<>r_zero then
  718. byte_zap(valueqa,trunc(valueqb),state.r[regc].valueq);
  719. end;
  720. { ZAPNOT }
  721. $31:
  722. begin
  723. if regc<>r_zero then
  724. byte_zap(valueqa,not(trunc(valueqb)),state.r[regc].valueq);
  725. end;
  726. { MSKQL }
  727. $32:
  728. begin
  729. { !!!!! no MSB support yet! }
  730. il:=$ff shl (tqwordrec(valueqb).low32 and $7);
  731. if (regc<>r_zero) then
  732. byte_zap(valueqa,il and $ff,state.r[regc].valueq);
  733. end;
  734. { SRL }
  735. $34:
  736. begin
  737. if regc<>r_zero then
  738. state.r[regc].valueq:=state.r[regc].valueq shr (valueqb and $3f);
  739. end;
  740. { EXTQL }
  741. $36:
  742. begin
  743. { !!!!! no MSB support yet! }
  744. shift_right_q(valueqa,(tqwordrec(valueqb).low32 and $7)*8,valueqa);
  745. if (regc<>r_zero) then
  746. state.r[regc].valueq:=valueqa;
  747. end;
  748. { SLL }
  749. $39:
  750. begin
  751. if regc<>r_zero then
  752. shift_left_q(valueqa,trunc(valueqb) and $3f,state.r[regc].valueq);
  753. end
  754. else
  755. illegalopcode(instructionpc);
  756. end;
  757. end;
  758. { ************* opcode $13 ************** }
  759. $13:
  760. begin
  761. rega:=(instruction and $3e00000) shr 21;
  762. regb:=(instruction and $1f0000) shr 16;
  763. regc:=instruction and $1f;
  764. valueqa:=state.r[rega].valueq;
  765. if (instruction and $1000)<>0 then
  766. valueqb:=(instruction and $1fe000) shr 13
  767. else
  768. valueqb:=state.r[regb].valueq;
  769. case (instruction and $fe0) shr 5 of
  770. { UMULH }
  771. $30:
  772. if regc<>31 then
  773. begin
  774. mulqword(valueqa,valueqb,oi);
  775. state.r[regc].valueq:=towordrec(oi).high64;
  776. end;
  777. else
  778. illegalopcode(instructionpc);
  779. end;
  780. end;
  781. { ************* opcode $17 ************** }
  782. $17:
  783. case (instruction and $ffe0) shr 5 of
  784. { MT_FPCR }
  785. $24:
  786. begin
  787. rega:=(instruction and $3e00000) shr 21;
  788. state.fpcr:=state.f[rega].valueq;
  789. end;
  790. { MF_FPCR }
  791. $25:
  792. begin
  793. rega:=(instruction and $3e00000) shr 21;
  794. if rega<>f_zero then
  795. state.f[rega].valueq:=state.fpcr;
  796. end;
  797. else
  798. illegalopcode(instructionpc);
  799. end;
  800. { ************* opcode $18 ************** }
  801. $18:
  802. case instruction and $ffff of
  803. { EXCB }
  804. $400:
  805. instructionignored('EXCN');
  806. else
  807. illegalopcode(instructionpc);
  808. end;
  809. { JMP,JSR,RET JSR_COROUTINE }
  810. $1a:
  811. begin
  812. rega:=(instruction and $3e00000) shr 21;
  813. regb:=(instruction and $1f0000) shr 16;
  814. va:=state.r[regb];
  815. va.low32:=va.low32 and $fffffffe;
  816. if rega<>31 then
  817. state.r[rega].valueq:=state.pc;
  818. state.pc:=va.valueq;
  819. {$ifdef FASTMEM}
  820. updatepc:=true;
  821. {$endif FASTMEM}
  822. end;
  823. { LDS }
  824. $22:
  825. begin
  826. { !!!!! no MSB support yet! }
  827. rega:=(instruction and $3e00000) shr 21;
  828. regb:=(instruction and $1f0000) shr 16;
  829. va.valueq:=state.r[regb].valueq+
  830. (int64(integer(instruction and $ffff)));
  831. if rega<>f_zero then
  832. begin
  833. { we need to copy the bit pattern! }
  834. dword(fs):=memory.readd(va.valueq);
  835. state.f[rega].valued:=fs;
  836. end;
  837. { !!!!!! no translation exceptions! }
  838. end;
  839. { LDT }
  840. $23:
  841. begin
  842. { !!!!! no MSB support yet! }
  843. rega:=(instruction and $3e00000) shr 21;
  844. regb:=(instruction and $1f0000) shr 16;
  845. va.valueq:=state.r[regb].valueq+
  846. (int64(integer(instruction and $ffff)));
  847. if rega<>f_zero then
  848. state.f[rega].valueq:=memory.readq(va.valueq);
  849. { !!!!!! no translation exceptions! }
  850. end;
  851. {$ifdef dummy}
  852. { !!!!!!!! STF }
  853. $24:
  854. begin
  855. { !!!!! no MSB support yet! }
  856. rega:=(instruction and $3e00000) shr 21;
  857. regb:=(instruction and $1f0000) shr 16;
  858. va.valueq:=state.r[regb].valueq+
  859. (int64(integer(instruction and $ffff)));
  860. fs:=state.f[rega].valued;
  861. memory.writed(va.valueq,longint(fs));
  862. { !!!!!! no tranlation exceptions! }
  863. end;
  864. { !!!!!!!!!!!! STG }
  865. $25:
  866. begin
  867. { !!!!! no MSB support yet! }
  868. rega:=(instruction and $3e00000) shr 21;
  869. regb:=(instruction and $1f0000) shr 16;
  870. va.valueq:=state.r[regb].valueq+
  871. (int64(integer(instruction and $ffff)));
  872. memory.writeq(va.valueq,state.f[rega].valueq);
  873. { !!!!!! no translation exceptions! }
  874. end;
  875. {$endif dummy}
  876. { !!!!!!!!!!!!! STS }
  877. $26:
  878. begin
  879. { !!!!! no MSB support yet! }
  880. rega:=(instruction and $3e00000) shr 21;
  881. regb:=(instruction and $1f0000) shr 16;
  882. va.valueq:=state.r[regb].valueq+
  883. (int64(integer(instruction and $ffff)));
  884. fs:=state.f[rega].valued;
  885. memory.writed(va.valueq,longint(fs));
  886. { !!!!!! no tranlation exceptions! }
  887. end;
  888. { STT }
  889. $27:
  890. begin
  891. { !!!!! no MSB support yet! }
  892. rega:=(instruction and $3e00000) shr 21;
  893. regb:=(instruction and $1f0000) shr 16;
  894. va.valueq:=state.r[regb].valueq+
  895. (int64(integer(instruction and $ffff)));
  896. memory.writeq(va.valueq,state.f[rega].valueq);
  897. { !!!!!! no translation exceptions! }
  898. end;
  899. { LDL }
  900. $28:
  901. begin
  902. { !!!!! no MSB support yet! }
  903. rega:=(instruction and $3e00000) shr 21;
  904. regb:=(instruction and $1f0000) shr 16;
  905. if rega<>r_zero then
  906. state.r[rega].low32:=memory.readalignedd(state.r[regb].valueq+
  907. (int64(integer(instruction and $ffff))));
  908. { sign extend }
  909. if state.r[rega].low32<0 then
  910. state.r[rega].high32:=$ffffffff
  911. else
  912. state.r[rega].high32:=0;
  913. end;
  914. { LDQ }
  915. $29:
  916. begin
  917. { !!!!! no MSB support yet! }
  918. rega:=(instruction and $3e00000) shr 21;
  919. regb:=(instruction and $1f0000) shr 16;
  920. if rega<>r_zero then
  921. state.r[rega].valueq:=memory.readalignedq(state.r[regb].valueq+
  922. (int64(integer(instruction and $ffff))));
  923. end;
  924. { STL }
  925. $2C:
  926. begin
  927. { !!!!! no MSB support yet! }
  928. rega:=(instruction and $3e00000) shr 21;
  929. regb:=(instruction and $1f0000) shr 16;
  930. va.valueq:=state.r[regb].valueq+
  931. (int64(integer(instruction and $ffff)));
  932. memory.writealignedd(va.valueq,state.r[rega].low32);
  933. end;
  934. { STQ }
  935. $2D:
  936. begin
  937. { !!!!! no MSB support yet! }
  938. rega:=(instruction and $3e00000) shr 21;
  939. regb:=(instruction and $1f0000) shr 16;
  940. va.valueq:=state.r[regb].valueq+
  941. (int64(integer(instruction and $ffff)));
  942. memory.writeq(va.valueq,state.r[rega].valueq);
  943. end;
  944. { BR,BSR }
  945. $30,$34:
  946. begin
  947. rega:=(instruction and $3e00000) shr 21;
  948. if rega<>31 then
  949. state.r[rega].valueq:=state.pc;
  950. state.pc:=state.pc+getbranchdisp;
  951. {$ifdef FASTMEM}
  952. updatepc:=true;
  953. {$endif FASTMEM}
  954. end;
  955. { BLSC }
  956. $38:
  957. begin
  958. rega:=(instruction and $3e00000) shr 21;
  959. va.valueq:=state.pc+getbranchdisp;
  960. if (state.r[rega].low32 and 1)=0 then
  961. begin
  962. state.pc:=va.valueq;
  963. {$ifdef FASTMEM}
  964. updatepc:=true;
  965. {$endif FASTMEM}
  966. end;
  967. end;
  968. { BEQ }
  969. $39:
  970. begin
  971. rega:=(instruction and $3e00000) shr 21;
  972. va.valueq:=state.pc+getbranchdisp;
  973. if state.r[rega].valueq=0 then
  974. begin
  975. state.pc:=va.valueq;
  976. {$ifdef FASTMEM}
  977. updatepc:=true;
  978. {$endif FASTMEM}
  979. end;
  980. end;
  981. { BLT }
  982. $3A:
  983. begin
  984. rega:=(instruction and $3e00000) shr 21;
  985. va.valueq:=state.pc+getbranchdisp;
  986. if state.r[rega].valueq<0 then
  987. begin
  988. state.pc:=va.valueq;
  989. {$ifdef FASTMEM}
  990. updatepc:=true;
  991. {$endif FASTMEM}
  992. end;
  993. end;
  994. { BLE }
  995. $3B:
  996. begin
  997. rega:=(instruction and $3e00000) shr 21;
  998. va.valueq:=state.pc+getbranchdisp;
  999. if state.r[rega].valueq<=0 then
  1000. begin
  1001. state.pc:=va.valueq;
  1002. {$ifdef FASTMEM}
  1003. updatepc:=true;
  1004. {$endif FASTMEM}
  1005. end;
  1006. end;
  1007. { BLBS }
  1008. $3C:
  1009. begin
  1010. rega:=(instruction and $3e00000) shr 21;
  1011. va.valueq:=state.pc+getbranchdisp;
  1012. if (state.r[rega].low32 and 1)<>0 then
  1013. begin
  1014. state.pc:=va.valueq;
  1015. {$ifdef FASTMEM}
  1016. updatepc:=true;
  1017. {$endif FASTMEM}
  1018. end;
  1019. end;
  1020. { BNE }
  1021. $3D:
  1022. begin
  1023. rega:=(instruction and $3e00000) shr 21;
  1024. va.valueq:=state.pc+getbranchdisp;
  1025. if state.r[rega].valueq<>0 then
  1026. begin
  1027. state.pc:=va.valueq;
  1028. {$ifdef FASTMEM}
  1029. updatepc:=true;
  1030. {$endif FASTMEM}
  1031. end;
  1032. end;
  1033. { BGE }
  1034. $3E:
  1035. begin
  1036. rega:=(instruction and $3e00000) shr 21;
  1037. va.valueq:=state.pc+getbranchdisp;
  1038. if state.r[rega].valueq>=0 then
  1039. begin
  1040. state.pc:=va.valueq;
  1041. {$ifdef FASTMEM}
  1042. updatepc:=true;
  1043. {$endif FASTMEM}
  1044. end;
  1045. end;
  1046. { BGT }
  1047. $3F:
  1048. begin
  1049. rega:=(instruction and $3e00000) shr 21;
  1050. va.valueq:=state.pc+getbranchdisp;
  1051. if state.r[rega].valueq>0 then
  1052. begin
  1053. state.pc:=va.valueq;
  1054. {$ifdef FASTMEM}
  1055. updatepc:=true;
  1056. {$endif FASTMEM}
  1057. end;
  1058. end;
  1059. else
  1060. illegalopcode(instructionpc);
  1061. end;
  1062. instrcount:=instrcount+1;
  1063. until false;
  1064. end;
  1065. destructor talphasim.done;
  1066. begin
  1067. { deallocate memory }
  1068. { memory.done; }
  1069. end;
  1070. procedure illelfformat;
  1071. begin
  1072. writeln('Illegal format of ELF');
  1073. halt(1);
  1074. end;
  1075. var
  1076. f : file;
  1077. elf64_hdr : telf64_hdr;
  1078. i : tindex;
  1079. j,q : qword;
  1080. b : byte;
  1081. elf64_phdr : pelf64_phdr_array;
  1082. const
  1083. et2str : array[0..6] of string[10] = ('ET_NONE','ET_REL','ET_EXEC',
  1084. 'ET_DYN','ET_CORE','ET_LOPROC',
  1085. 'ET_HIPROC');
  1086. em2str : array[0..11] of string[10] = ('EM_NONE','EM_M32','EM_SPARC',
  1087. 'EM_386','EM_68K','EM_88K',
  1088. 'EM_486','EM_860','EM_MIPS','',
  1089. 'EM_MIPS_RS4_BE','EM_SPARC64');
  1090. begin
  1091. if paramcount<>1 then
  1092. begin
  1093. writeln('Usage ALPHAEMU <elf-executable>');
  1094. halt(1);
  1095. end;
  1096. {$ifdef DEBUG}
  1097. write('Init... ');
  1098. {$endif DEBUG}
  1099. assign(f,paramstr(1));
  1100. {$I-}
  1101. reset(f,1);
  1102. {$I+}
  1103. if ioresult<>0 then
  1104. begin
  1105. writeln;
  1106. writeln('Can''t open input file ',paramstr(1));
  1107. halt(1);
  1108. end;
  1109. blockread(f,elf64_hdr,sizeof(elf64_hdr));
  1110. {$ifdef DEBUG}
  1111. writeln('Signature:');
  1112. for i:=0 to 15 do
  1113. write(elf64_hdr.e_ident[i],'(',ord(elf64_hdr.e_ident[i]),') ');
  1114. writeln;
  1115. writeln('ELF type: ',et2str[elf64_hdr.e_type]);
  1116. case elf64_hdr.e_machine of
  1117. 0..11:
  1118. writeln('ELF machine: ',em2str[elf64_hdr.e_machine]);
  1119. 15:
  1120. writeln('ELF machine: EM_PARISC');
  1121. 18:
  1122. writeln('ELF machine: EM_SPARC32PLUS');
  1123. 20:
  1124. writeln('ELF machine: EM_PPC');
  1125. $9026:
  1126. writeln('ELF machine: EM_ALPHA');
  1127. else
  1128. illelfformat;
  1129. end;
  1130. writeln('ELF header size: $',hexstr(elf64_hdr.e_ehsize,8));
  1131. writeln('Entry point: $',qword2str(elf64_hdr.e_entry));
  1132. writeln('Program header table file offset: $',qword2str(elf64_hdr.e_phoff));
  1133. writeln('Number of program headers : $',hexstr(elf64_hdr.e_phnum,8));
  1134. writeln('Size of one program header: $',hexstr(elf64_hdr.e_phentsize,8));
  1135. writeln('Section header table file offset: $',qword2str(elf64_hdr.e_shoff));
  1136. { writeln('Section name index: $',hexstr(elf64_hdr.e_shstrndx,8)); }
  1137. {$endif}
  1138. if (elf64_hdr.e_ident[0]<>chr(127)) or
  1139. (elf64_hdr.e_ident[1]<>'E') or
  1140. (elf64_hdr.e_ident[2]<>'L') or
  1141. (elf64_hdr.e_ident[3]<>'F') or
  1142. (elf64_hdr.e_type<>2) or
  1143. (elf64_hdr.e_machine<>$9026) then
  1144. illelfformat;
  1145. { load programm headers }
  1146. getmem(elf64_phdr,elf64_hdr.e_phentsize*elf64_hdr.e_phnum);
  1147. seek(f,trunc(elf64_hdr.e_phoff));
  1148. blockread(f,elf64_phdr^,elf64_hdr.e_phentsize*elf64_hdr.e_phnum);
  1149. for i:=0 to elf64_hdr.e_phnum-1 do
  1150. begin
  1151. {$ifdef DEBUG}
  1152. writeln('Programm header ',i);
  1153. dump_phdr(elf64_phdr^[i]);
  1154. {$endif DEBUG}
  1155. end;
  1156. { ok, now init the emulator }
  1157. sim.init;
  1158. {$ifdef FPC}
  1159. stopsim:=@_stopsim;
  1160. {$else FPC}
  1161. stopsim:=_stopsim;
  1162. {$endif FPC}
  1163. {$ifdef DEBUG}
  1164. writeln('OK');
  1165. write('Loading memory... ');
  1166. {$endif DEBUG}
  1167. { load memory }
  1168. for i:=0 to elf64_hdr.e_phnum-1 do
  1169. begin
  1170. {$ifdef DEBUG}
  1171. write(i+1,' ');
  1172. {$endif DEBUG}
  1173. sim.memory.allocate(elf64_phdr^[i].p_vaddr,elf64_phdr^[i].p_memsz);
  1174. seek(f,trunc(elf64_phdr^[i].p_offset));
  1175. j:=0;
  1176. { can we speedup the loading? }
  1177. if (tqwordrec(elf64_phdr^[i].p_filesz).low32 and $7)=0 then
  1178. while j<elf64_phdr^[i].p_filesz do
  1179. begin
  1180. blockread(f,q,8);
  1181. sim.memory.writeq(j+elf64_phdr^[i].p_vaddr,q);
  1182. j:=j+8;
  1183. end
  1184. else
  1185. while j<elf64_phdr^[i].p_filesz do
  1186. begin
  1187. blockread(f,b,1);
  1188. sim.memory.writeb(j+elf64_phdr^[i].p_vaddr,b);
  1189. j:=j+1;
  1190. end;
  1191. end;
  1192. { clean up from the file loading }
  1193. freemem(elf64_phdr,elf64_hdr.e_phentsize*elf64_hdr.e_phnum);
  1194. close(f);
  1195. {$ifdef DEBUG}
  1196. writeln('OK');
  1197. writeln('Running program ...');
  1198. {$endif DEBUG}
  1199. sim.run(elf64_hdr.e_entry);
  1200. {$ifdef DEBUG}
  1201. writeln('Ready');
  1202. {$endif DEBUG}
  1203. stopsim;
  1204. sim.done;
  1205. end.
  1206. {
  1207. $Log$
  1208. Revision 1.2 2002-09-07 15:40:36 peter
  1209. * old logs removed and tabs fixed
  1210. }