alphasim.pas 43 KB

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