alphasim.pas 43 KB

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