Advertisement
Guest User

Untitled

a guest
Apr 23rd, 2018
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.69 KB | None | 0 0
  1. #include <assert.h>
  2. #include <stdarg.h>
  3. #include <limits.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <stdbool.h>
  8.  
  9. #define NREG (32)
  10. #define PAGESIZE_WIDTH (2)
  11. #define PAGESIZE (1<<PAGESIZE_WIDTH)
  12. #define NPAGES (2048)
  13. #define RAM_PAGES (8)
  14. #define RAM_SIZE (RAM_PAGES * PAGESIZE)
  15. #define SWAP_PAGES (128)
  16. #define SWAP_SIZE (SWAP_PAGES * PAGESIZE)
  17. #undef DEBUG
  18.  
  19. #define ADD (0)
  20. #define ADDI (1)
  21. #define SUB (2)
  22. #define SUBI (3)
  23. #define SGE (4)
  24. #define SGT (5)
  25. #define SEQ (6)
  26. #define BT (7)
  27. #define BF (8)
  28. #define BA (9)
  29. #define ST (10)
  30. #define LD (11)
  31. #define CALL (12)
  32. #define JMP (13)
  33. #define MUL (14)
  34. #define SEQI (15)
  35. #define HALT (16)
  36.  
  37. char* mnemonics[] = {
  38. [ADD] = "add",
  39. [ADDI] = "addi",
  40. [SUB] = "sub",
  41. [SUBI] = "subi",
  42. [SGE] = "sge",
  43. [SGT] = "sgt",
  44. [SEQ] = "seq",
  45. [SEQI] = "seqi",
  46. [BT] = "bt",
  47. [BF] = "bf",
  48. [BA] = "ba",
  49. [ST] = "st",
  50. [LD] = "ld",
  51. [CALL] = "call",
  52. [JMP] = "jmp",
  53. [MUL] = "mul",
  54. [HALT] = "halt",
  55. };
  56.  
  57. typedef struct {
  58. unsigned pc; /* Program counter. */
  59. unsigned reg[NREG]; /* Registers. */
  60. } cpu_t;
  61.  
  62. typedef struct {
  63. unsigned int page:27; /* Swap or RAM page. */
  64. unsigned int inmemory:1; /* Page is in memory. */
  65. unsigned int ondisk:1; /* Page is on disk. */
  66. unsigned int modified:1; /* Page was modified while in memory. */
  67. unsigned int referenced:1; /* Page was referenced recently. */
  68. unsigned int readonly:1; /* Error if written to (not checked). */
  69. } page_table_entry_t;
  70.  
  71. typedef struct {
  72. page_table_entry_t* owner; /* Owner of this phys page. */
  73. unsigned page; /* Swap page of page if assigned. */
  74. } coremap_entry_t;
  75.  
  76. static unsigned long long num_pagefault; /* Statistics. */
  77. static page_table_entry_t page_table[NPAGES]; /* OS data structure. */
  78. static coremap_entry_t coremap[RAM_PAGES]; /* OS data structure. */
  79. static unsigned memory[RAM_SIZE]; /* Hardware: RAM. */
  80. static unsigned swap[SWAP_SIZE]; /* Hardware: disk. */
  81. static unsigned (*replace)(void); /* Page repl. alg. */
  82.  
  83. int x;
  84.  
  85. unsigned make_instr(unsigned opcode, unsigned dest, unsigned s1, unsigned s2)
  86. {
  87. return (opcode << 26) | (dest << 21) | (s1 << 16) | (s2 & 0xffff);
  88. }
  89.  
  90. unsigned extract_opcode(unsigned instr)
  91. {
  92. return instr >> 26;
  93. }
  94.  
  95. unsigned extract_dest(unsigned instr)
  96. {
  97. return (instr >> 21) & 0x1f;
  98. }
  99.  
  100. unsigned extract_source1(unsigned instr)
  101. {
  102. return (instr >> 16) & 0x1f;
  103. }
  104.  
  105. signed extract_constant(unsigned instr)
  106. {
  107. return (short)(instr & 0xffff);
  108. }
  109.  
  110. void error(char* fmt, ...)
  111. {
  112. va_list ap;
  113. char buf[BUFSIZ];
  114.  
  115. va_start(ap, fmt);
  116. vsprintf(buf, fmt, ap);
  117. fprintf(stderr, "error: %s\n", buf);
  118. exit(1);
  119. }
  120.  
  121. static void read_page(unsigned phys_page, unsigned swap_page)
  122. {
  123. memcpy(&memory[phys_page * PAGESIZE],
  124. &swap[swap_page * PAGESIZE],
  125. PAGESIZE * sizeof(unsigned));
  126. }
  127.  
  128. static void write_page(unsigned phys_page, unsigned swap_page)
  129. {
  130. memcpy(&swap[swap_page * PAGESIZE],
  131. &memory[phys_page * PAGESIZE],
  132. PAGESIZE * sizeof(unsigned));
  133. }
  134.  
  135. static unsigned new_swap_page()
  136. {
  137. static int count;
  138.  
  139. assert(count < SWAP_PAGES);
  140.  
  141. return count++;
  142. }
  143.  
  144. int ind;
  145. static unsigned fifo_page_replace()
  146. {
  147. int page;
  148. ind = (ind + 1) % RAM_PAGES;
  149. page = ind;
  150.  
  151. assert(page < RAM_PAGES);
  152. return page;
  153.  
  154. }
  155.  
  156. static unsigned second_chance_replace()
  157. {
  158. int page;
  159.  
  160. page = INT_MAX;
  161.  
  162. assert(page < RAM_PAGES);
  163. }
  164.  
  165. static unsigned take_phys_page()
  166. {
  167. unsigned page; /* Page to be replaced. */
  168.  
  169. page = (*replace)();
  170.  
  171. return page;
  172. }
  173.  
  174. static void pagefault(unsigned virt_page)
  175. {
  176. unsigned page;
  177.  
  178. num_pagefault += 1;
  179.  
  180. page = take_phys_page();
  181.  
  182.  
  183. //Flytta gammalt värde till hårddisk
  184. if (coremap[page].page != 0) {
  185. page_table_entry_t* owner = coremap[page].owner;
  186. owner->inmemory = 0;
  187. owner->ondisk = 1;
  188. unsigned swap = new_swap_page();
  189. printf("%d\n", swap);
  190. write_page(page,swap);
  191. owner->page = swap;
  192. }
  193. //Flytta värde från hårddisk till RAM
  194. if (page_table[virt_page].ondisk == 1) {
  195. read_page(page,page_table[virt_page].page);
  196. }
  197.  
  198. if(page_table[virt_page].ondisk == 1 && coremap[page].page != 0) {
  199. printf("jag vill hem");
  200. }
  201.  
  202. //Uppdatera page_table till ny page
  203. page_table[virt_page].page = page;
  204. page_table[virt_page].inmemory = 1;
  205. page_table[virt_page].ondisk = 0;
  206. //Uppdatera coremap till ny virtuell adress
  207. coremap[page].page = virt_page;
  208. coremap[page].owner = &page_table[virt_page];
  209. }
  210.  
  211. static void translate(unsigned virt_addr, unsigned* phys_addr, bool write)
  212. {
  213. unsigned virt_page;
  214. unsigned offset;
  215.  
  216. virt_page = virt_addr / PAGESIZE;
  217. offset = virt_addr & (PAGESIZE - 1);
  218.  
  219. /*printf("%s\n", "virt_addr");
  220. printf("%i\n", virt_addr);
  221. printf("%s\n", "phys");
  222. printf("%i\n", phys_addr);
  223.  
  224.  
  225. for(int i = 0; i < NPAGES; i++) {
  226. printf("%i\n", page_table[i].page);
  227. }*/
  228.  
  229. if (!page_table[virt_page].inmemory)
  230. pagefault(virt_page);
  231.  
  232. page_table[virt_page].referenced = 1;
  233.  
  234. if (write)
  235. page_table[virt_page].modified = 1;
  236.  
  237. *phys_addr = page_table[virt_page].page * PAGESIZE + offset;
  238. }
  239.  
  240. static unsigned read_memory(unsigned* memory, unsigned addr)
  241. {
  242. unsigned phys_addr;
  243.  
  244. translate(addr, &phys_addr, false);
  245.  
  246. return memory[phys_addr];
  247. }
  248.  
  249. static void write_memory(unsigned* memory, unsigned addr, unsigned data)
  250. {
  251. unsigned phys_addr;
  252.  
  253. translate(addr, &phys_addr, true);
  254.  
  255. memory[phys_addr] = data;
  256. }
  257.  
  258. void read_program(char* file, unsigned memory[], int* ninstr)
  259. {
  260. FILE* in;
  261. int opcode;
  262. int a, b, c;
  263. int i;
  264. char buf[BUFSIZ];
  265. char text[BUFSIZ];
  266. int n;
  267. int line;
  268.  
  269. /* Find out the number of mnemonics. */
  270. n = sizeof mnemonics / sizeof mnemonics[0];
  271.  
  272. in = fopen(file, "r");
  273.  
  274. if (in == NULL)
  275. error("cannot open file");
  276.  
  277. line = 0;
  278.  
  279. while (fgets(buf, sizeof buf, in) != NULL) {
  280. if (buf[0] == ';')
  281. continue;
  282.  
  283. if (sscanf(buf, "%s %d,%d,%d", text, &a, &b, &c) != 4)
  284. error("syntax error near: \"%s\"", buf);
  285.  
  286. opcode = -1;
  287.  
  288. for (i = 0; i < n; ++i) {
  289. if (strcmp(text, mnemonics[i]) == 0) {
  290. opcode = i;
  291. break;
  292. }
  293. }
  294.  
  295. if (opcode < 0)
  296. error("syntax error near: \"%s\"", text);
  297.  
  298. write_memory(memory, line, make_instr(opcode, a, b, c));
  299.  
  300. line += 1;
  301. }
  302.  
  303. *ninstr = line;
  304. }
  305.  
  306. int run(int argc, char** argv)
  307. {
  308. char* file;
  309. cpu_t cpu;
  310. int i;
  311. int j;
  312. int ninstr;
  313. unsigned instr;
  314. unsigned opcode;
  315. unsigned source_reg1;
  316. int constant;
  317. unsigned dest_reg;
  318. int source1;
  319. int source2;
  320. int dest;
  321. unsigned data;
  322. bool proceed;
  323. bool increment_pc;
  324. bool writeback;
  325.  
  326. if (argc > 1)
  327. file = argv[1];
  328. else
  329. file = "a.s";
  330.  
  331. read_program(file, memory, &ninstr);
  332.  
  333. /* First instruction to execute is at address 0. */
  334. cpu.pc = 0;
  335. cpu.reg[0] = 0;
  336.  
  337. proceed = true;
  338.  
  339. while (proceed) {
  340.  
  341. /* Fetch next instruction to execute. */
  342. instr = read_memory(memory, cpu.pc);
  343.  
  344. /* Decode the instruction. */
  345. opcode = extract_opcode(instr);
  346. source_reg1 = extract_source1(instr);
  347. constant = extract_constant(instr);
  348. dest_reg = extract_dest(instr);
  349.  
  350. /* Fetch operands. */
  351. source1 = cpu.reg[source_reg1];
  352. source2 = cpu.reg[constant & (NREG-1)];
  353.  
  354. increment_pc = true;
  355. writeback = true;
  356.  
  357. //printf("pc = %3d: ", cpu.pc);
  358.  
  359. switch (opcode) {
  360. case ADD:
  361. //puts("ADD");
  362. dest = source1 + source2;
  363. break;
  364.  
  365. case ADDI:
  366. //puts("ADDI");
  367. dest = source1 + constant;
  368. break;
  369.  
  370. case SUB:
  371. //puts("SUB");
  372. dest = source1 - source2;
  373. break;
  374.  
  375. case SUBI:
  376. //puts("SUBI");
  377. dest = source1 - constant;
  378. break;
  379.  
  380. case MUL:
  381. //puts("MUL");
  382. dest = source1 * source2;
  383. break;
  384.  
  385. case SGE:
  386. //puts("SGE");
  387. dest = source1 >= source2;
  388. break;
  389.  
  390. case SGT:
  391. //puts("SGT");
  392. dest = source1 > source2;
  393. break;
  394.  
  395. case SEQ:
  396. //puts("SEQ");
  397. dest = source1 == source2;
  398. break;
  399.  
  400. case SEQI:
  401. //puts("SEQI");
  402. dest = source1 == constant;
  403. break;
  404.  
  405. case BT:
  406. //puts("BT");
  407. writeback = false;
  408. if (source1 != 0) {
  409. cpu.pc = constant;
  410. increment_pc = false;
  411. }
  412. break;
  413.  
  414. case BF:
  415. //puts("BF");
  416. writeback = false;
  417. if (source1 == 0) {
  418. cpu.pc = constant;
  419. increment_pc = false;
  420. }
  421. break;
  422.  
  423. case BA:
  424. //puts("BA");
  425. writeback = false;
  426. increment_pc = false;
  427. cpu.pc = constant;
  428. break;
  429.  
  430. case LD:
  431. //puts("LD");
  432. data = read_memory(memory, source1 + constant);
  433. dest = data;
  434. break;
  435.  
  436. case ST:
  437. //puts("ST");
  438. data = cpu.reg[dest_reg];
  439. write_memory(memory, source1 + constant, data);
  440. writeback = false;
  441. break;
  442.  
  443. case CALL:
  444. //puts("CALL");
  445. increment_pc = false;
  446. dest = cpu.pc + 1;
  447. dest_reg = 31;
  448. cpu.pc = constant;
  449. break;
  450.  
  451. case JMP:
  452. //puts("JMP");
  453. increment_pc = false;
  454. writeback = false;
  455. cpu.pc = source1;
  456. break;
  457.  
  458. case HALT:
  459. //puts("HALT");
  460. increment_pc = false;
  461. writeback = false;
  462. proceed = false;
  463. break;
  464.  
  465. default:
  466. error("illegal instruction at pc = %d: opcode = %d\n",
  467. cpu.pc, opcode);
  468. }
  469.  
  470. if (writeback && dest_reg != 0)
  471. cpu.reg[dest_reg] = dest;
  472.  
  473. if (increment_pc)
  474. cpu.pc += 1;
  475.  
  476. #ifdef DEBUG
  477. i = 0;
  478. while (i < NREG) {
  479. for (j = 0; j < 4; ++j, ++i) {
  480. if (j > 0)
  481. printf("| ");
  482. printf("R%02d = %-12d", i, cpu.reg[i]);
  483. }
  484. printf("\n");
  485. }
  486. #endif
  487. }
  488.  
  489. i = 0;
  490. while (i < NREG) {
  491. for (j = 0; j < 4; ++j, ++i) {
  492. if (j > 0)
  493. printf("| ");
  494. printf("R%02d = %-12d", i, cpu.reg[i]);
  495. }
  496. printf("\n");
  497.  
  498.  
  499. }
  500. return 0;
  501. }
  502.  
  503. int main(int argc, char** argv)
  504. {
  505. #if 1
  506. replace = fifo_page_replace;
  507. #else
  508. replace = second_chance_replace;
  509. #endif
  510.  
  511. run(argc, argv);
  512.  
  513. printf("%llu page faults\n", num_pagefault);
  514. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement