├── README.md ├── lab1-data ├── Driverhdrs.pm ├── Driverlib.pm ├── Makefile ├── README ├── bits.c ├── bits.h ├── btest.c ├── btest.h ├── decl.c ├── dlc ├── driver.pl ├── fshow.c ├── ishow.c └── tests.c ├── lab2-bomb ├── README ├── bomb └── bomb.c ├── lab3-buffer-32-bit ├── bufbomb ├── hex2raw └── makecookie ├── lab3-buffer-64-bit ├── README.txt ├── cookie.txt ├── ctarget ├── farm.c ├── hex2raw └── rtarget ├── lab4-architecture-y86-64 ├── Makefile ├── README ├── archlab.pdf ├── sim │ ├── Makefile │ ├── README │ ├── misc │ │ ├── Makefile │ │ ├── README │ │ ├── examples.c │ │ ├── hcl.lex │ │ ├── hcl.tab.c │ │ ├── hcl.tab.h │ │ ├── hcl.y │ │ ├── isa.c │ │ ├── isa.h │ │ ├── lex.yy.c │ │ ├── mux4.hcl │ │ ├── node.c │ │ ├── node.h │ │ ├── outgen.c │ │ ├── outgen.h │ │ ├── yas-grammar.c │ │ ├── yas-grammar.lex │ │ ├── yas.c │ │ ├── yas.h │ │ └── yis.c │ ├── pipe │ │ ├── Makefile │ │ ├── README │ │ ├── benchmark.pl │ │ ├── check-len.pl │ │ ├── correctness.pl │ │ ├── gen-driver.pl │ │ ├── ncopy.c │ │ ├── ncopy.ys │ │ ├── pipe-1w.hcl │ │ ├── pipe-broken.hcl │ │ ├── pipe-btfnt.hcl │ │ ├── pipe-full.hcl │ │ ├── pipe-lf.hcl │ │ ├── pipe-nobypass.hcl │ │ ├── pipe-nt.hcl │ │ ├── pipe-std.hcl │ │ ├── pipe.tcl │ │ ├── pipeline.h │ │ ├── psim.c │ │ ├── sim.h │ │ └── stages.h │ ├── ptest │ │ ├── Makefile │ │ ├── README │ │ ├── ctest.pl │ │ ├── etest.pl │ │ ├── htest.pl │ │ ├── jtest.pl │ │ ├── optest.pl │ │ └── tester.pm │ ├── seq │ │ ├── Makefile │ │ ├── README │ │ ├── seq+-std.hcl │ │ ├── seq+.tcl │ │ ├── seq-full.hcl │ │ ├── seq-std.hcl │ │ ├── seq.tcl │ │ ├── sim.h │ │ └── ssim.c │ └── y86-code │ │ ├── Makefile │ │ ├── README │ │ ├── abs-asum-cmov.ys │ │ ├── abs-asum-jmp.ys │ │ ├── asum.ys │ │ ├── asumi.ys │ │ ├── asumr.ys │ │ ├── cjr.ys │ │ ├── j-cc.ys │ │ ├── poptest.ys │ │ ├── prog1.ys │ │ ├── prog10.ys │ │ ├── prog2.ys │ │ ├── prog3.ys │ │ ├── prog4.ys │ │ ├── prog5.ys │ │ ├── prog6.ys │ │ ├── prog7.ys │ │ ├── prog8.ys │ │ ├── prog9.ys │ │ ├── pushquestion.ys │ │ ├── pushtest.ys │ │ └── ret-hazard.ys └── simguide.pdf ├── lab4-architecture-y86 ├── Makefile ├── README ├── archlab.pdf ├── archlab.ps ├── sim │ ├── Makefile │ ├── README │ ├── misc │ │ ├── Makefile │ │ ├── README │ │ ├── examples.c │ │ ├── hcl.lex │ │ ├── hcl.y │ │ ├── isa.c │ │ ├── isa.h │ │ ├── mux4.hcl │ │ ├── node.c │ │ ├── node.h │ │ ├── outgen.c │ │ ├── outgen.h │ │ ├── yas-grammar.c │ │ ├── yas-grammar.lex │ │ ├── yas.c │ │ ├── yas.h │ │ └── yis.c │ ├── pipe │ │ ├── Makefile │ │ ├── README │ │ ├── benchmark.pl │ │ ├── check-len.pl │ │ ├── correctness.pl │ │ ├── gen-driver.pl │ │ ├── ncopy.c │ │ ├── ncopy.ys │ │ ├── pipe-1w.hcl │ │ ├── pipe-broken.hcl │ │ ├── pipe-btfnt.hcl │ │ ├── pipe-full.hcl │ │ ├── pipe-lf.hcl │ │ ├── pipe-nobypass.hcl │ │ ├── pipe-nt.hcl │ │ ├── pipe-std.hcl │ │ ├── pipe.tcl │ │ ├── pipeline.h │ │ ├── psim.c │ │ ├── sim.h │ │ └── stages.h │ ├── ptest │ │ ├── Makefile │ │ ├── README │ │ ├── ctest.pl │ │ ├── etest.pl │ │ ├── htest.pl │ │ ├── jtest.pl │ │ ├── optest.pl │ │ └── tester.pm │ ├── seq │ │ ├── Makefile │ │ ├── README │ │ ├── seq+-std.hcl │ │ ├── seq+.tcl │ │ ├── seq-full.hcl │ │ ├── seq-std.hcl │ │ ├── seq.tcl │ │ ├── sim.h │ │ └── ssim.c │ └── y86-code │ │ ├── Makefile │ │ ├── README │ │ ├── abs-asum-cmov.ys │ │ ├── abs-asum-jmp.ys │ │ ├── asum.ys │ │ ├── asumi.ys │ │ ├── asuml.ys │ │ ├── asumr.ys │ │ ├── cjr.ys │ │ ├── j-cc.ys │ │ ├── poptest.ys │ │ ├── prog1.ys │ │ ├── prog10.ys │ │ ├── prog2.ys │ │ ├── prog3.ys │ │ ├── prog4.ys │ │ ├── prog5.ys │ │ ├── prog6.ys │ │ ├── prog7.ys │ │ ├── prog8.ys │ │ ├── prog9.ys │ │ ├── pushquestion.ys │ │ ├── pushtest.ys │ │ └── ret-hazard.ys └── simguide.pdf ├── lab5-cache ├── Makefile ├── README ├── cachelab.c ├── cachelab.h ├── csim-ref ├── csim.c ├── driver.py ├── test-csim ├── test-trans.c ├── tracegen.c ├── traces │ ├── dave.trace │ ├── long.trace │ ├── trans.trace │ ├── yi.trace │ └── yi2.trace └── trans.c ├── lab6-performance ├── Makefile ├── README ├── clock.c ├── clock.h ├── config.h ├── defs.h ├── driver.c ├── fcyc.c ├── fcyc.h └── kernels.c ├── lab7-shell ├── Makefile ├── README ├── myint.c ├── myspin.c ├── mysplit.c ├── mystop.c ├── sdriver.pl ├── trace01.txt ├── trace02.txt ├── trace03.txt ├── trace04.txt ├── trace05.txt ├── trace06.txt ├── trace07.txt ├── trace08.txt ├── trace09.txt ├── trace10.txt ├── trace11.txt ├── trace12.txt ├── trace13.txt ├── trace14.txt ├── trace15.txt ├── trace16.txt ├── tsh.c ├── tshref └── tshref.out ├── lab8-malloc ├── Makefile ├── README ├── clock.c ├── clock.h ├── config.h ├── fcyc.c ├── fcyc.h ├── fsecs.c ├── fsecs.h ├── ftimer.c ├── ftimer.h ├── mdriver.c ├── memlib.c ├── memlib.h ├── mm.c ├── mm.h ├── short1-bal.rep ├── short2-bal.rep └── traces │ ├── amptjp-bal.rep │ ├── binary-bal.rep │ ├── binary2-bal.rep │ ├── cccp-bal.rep │ ├── coalescing-bal.rep │ ├── cp-decl-bal.rep │ ├── expr-bal.rep │ ├── random-bal.rep │ ├── random2-bal.rep │ ├── realloc-bal.rep │ └── realloc2-bal.rep └── lab9-proxy ├── Makefile ├── README ├── csapp.c ├── csapp.h ├── driver.sh ├── free-port.sh ├── nop-server.py ├── port-for-user.pl ├── proxy.c └── tiny ├── Makefile ├── README ├── cgi-bin ├── Makefile └── adder.c ├── csapp.c ├── csapp.h ├── godzilla.gif ├── godzilla.jpg ├── home.html └── tiny.c /lab1-data/Driverhdrs.pm: -------------------------------------------------------------------------------- 1 | # 2 | # This file contains configuration variables for drivers. 3 | # It was generated by genhdrs.pl. Do not modify it. 4 | # 5 | package Driverhdrs; 6 | 7 | $LAB = "datalab"; 8 | $SERVER_NAME = "changeme.ics.cs.cmu.edu"; 9 | $SERVER_PORT = 8081; 10 | $COURSE_NAME = "csapp"; 11 | $AUTOGRADE_TIMEOUT = 0; 12 | 1; 13 | -------------------------------------------------------------------------------- /lab1-data/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Makefile that builds btest and other helper programs for the CS:APP data lab 3 | # 4 | CC = gcc 5 | CFLAGS = -O -Wall -m32 6 | LIBS = -lm 7 | 8 | all: btest fshow ishow 9 | 10 | btest: btest.c bits.c decl.c tests.c btest.h bits.h 11 | $(CC) $(CFLAGS) $(LIBS) -o btest bits.c btest.c decl.c tests.c 12 | 13 | fshow: fshow.c 14 | $(CC) $(CFLAGS) -o fshow fshow.c 15 | 16 | ishow: ishow.c 17 | $(CC) $(CFLAGS) -o ishow ishow.c 18 | 19 | # Forces a recompile. Used by the driver program. 20 | btestexplicit: 21 | $(CC) $(CFLAGS) $(LIBS) -o btest bits.c btest.c decl.c tests.c 22 | 23 | clean: 24 | rm -f *.o btest fshow ishow *~ 25 | 26 | 27 | -------------------------------------------------------------------------------- /lab1-data/bits.h: -------------------------------------------------------------------------------- 1 | 2 | int bitAnd(int, int); 3 | int test_bitAnd(int, int); 4 | int getByte(int, int); 5 | int test_getByte(int, int); 6 | int logicalShift(int, int); 7 | int test_logicalShift(int, int); 8 | int bitCount(int); 9 | int test_bitCount(int); 10 | int bang(int); 11 | int test_bang(int); 12 | int tmin(); 13 | int test_tmin(); 14 | int fitsBits(int, int); 15 | int test_fitsBits(int, int); 16 | int divpwr2(int, int); 17 | int test_divpwr2(int, int); 18 | int negate(int); 19 | int test_negate(int); 20 | int isPositive(int); 21 | int test_isPositive(int); 22 | int isLessOrEqual(int, int); 23 | int test_isLessOrEqual(int, int); 24 | int ilog2(int); 25 | int test_ilog2(int); 26 | unsigned float_neg(unsigned); 27 | unsigned test_float_neg(unsigned); 28 | unsigned float_i2f(int); 29 | unsigned test_float_i2f(int); 30 | unsigned float_twice(unsigned); 31 | unsigned test_float_twice(unsigned); 32 | -------------------------------------------------------------------------------- /lab1-data/btest.h: -------------------------------------------------------------------------------- 1 | /* 2 | * CS:APP Data Lab 3 | */ 4 | 5 | /* Declare different function types */ 6 | typedef int (*funct_t) (void); 7 | typedef int (*funct1_t)(int); 8 | typedef int (*funct2_t)(int, int); 9 | typedef int (*funct3_t)(int, int, int); 10 | 11 | /* Combine all the information about a function and its tests as structure */ 12 | typedef struct { 13 | char *name; /* String name */ 14 | funct_t solution_funct; /* Function */ 15 | funct_t test_funct; /* Test function */ 16 | int args; /* Number of function arguments */ 17 | char *ops; /* List of legal operators. Special case: "$" for floating point */ 18 | int op_limit; /* Max number of ops allowed in solution */ 19 | int rating; /* Problem rating (1 -- 4) */ 20 | int arg_ranges[3][2]; /* Argument ranges. Always defined for 3 args, even if */ 21 | /* the function takes fewer. Special case: First arg */ 22 | /* must be set to {1,1} for f.p. puzzles */ 23 | } test_rec, *test_ptr; 24 | 25 | extern test_rec test_set[]; 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /lab1-data/decl.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define TMin INT_MIN 6 | #define TMax INT_MAX 7 | 8 | #include "btest.h" 9 | #include "bits.h" 10 | 11 | test_rec test_set[] = { 12 | 13 | 14 | 15 | 16 | 17 | {"bitAnd", (funct_t) bitAnd, (funct_t) test_bitAnd, 2, "| ~", 8, 1, 18 | {{TMin, TMax},{TMin,TMax},{TMin,TMax}}}, 19 | {"getByte", (funct_t) getByte, (funct_t) test_getByte, 2, 20 | "! ~ & ^ | + << >>", 6, 2, 21 | {{TMin, TMax},{0,3},{TMin,TMax}}}, 22 | {"logicalShift", (funct_t) logicalShift, (funct_t) test_logicalShift, 23 | 2, "! ~ & ^ | + << >>", 20, 3, 24 | {{TMin, TMax},{0,31},{TMin,TMax}}}, 25 | {"bitCount", (funct_t) bitCount, (funct_t) test_bitCount, 1, "! ~ & ^ | + << >>", 40, 4, 26 | {{TMin, TMax},{TMin,TMax},{TMin,TMax}}}, 27 | {"bang", (funct_t) bang, (funct_t) test_bang, 1, 28 | "~ & ^ | + << >>", 12, 4, 29 | {{TMin, TMax},{TMin,TMax},{TMin,TMax}}}, 30 | {"tmin", (funct_t) tmin, (funct_t) test_tmin, 0, "! ~ & ^ | + << >>", 4, 1, 31 | {{TMin, TMax},{TMin,TMax},{TMin,TMax}}}, 32 | {"fitsBits", (funct_t) fitsBits, (funct_t) test_fitsBits, 2, 33 | "! ~ & ^ | + << >>", 15, 2, 34 | {{TMin, TMax},{1,32},{TMin,TMax}}}, 35 | {"divpwr2", (funct_t) divpwr2, (funct_t) test_divpwr2, 2, 36 | "! ~ & ^ | + << >>", 15, 2, 37 | {{TMin, TMax},{0,30},{TMin,TMax}}}, 38 | {"negate", (funct_t) negate, (funct_t) test_negate, 1, 39 | "! ~ & ^ | + << >>", 5, 2, 40 | {{TMin, TMax},{TMin,TMax},{TMin,TMax}}}, 41 | {"isPositive", (funct_t) isPositive, (funct_t) test_isPositive, 1, 42 | "! ~ & ^ | + << >>", 8, 3, 43 | {{TMin, TMax},{TMin,TMax},{TMin,TMax}}}, 44 | {"isLessOrEqual", (funct_t) isLessOrEqual, (funct_t) test_isLessOrEqual, 2, 45 | "! ~ & ^ | + << >>", 24, 3, 46 | {{TMin, TMax},{TMin,TMax},{TMin,TMax}}}, 47 | {"ilog2", (funct_t) ilog2, (funct_t) test_ilog2, 1, "! ~ & ^ | + << >>", 90, 4, 48 | {{1, TMax},{TMin,TMax},{TMin,TMax}}}, 49 | {"float_neg", (funct_t) float_neg, (funct_t) test_float_neg, 1, 50 | "$", 10, 2, 51 | {{1, 1},{1,1},{1,1}}}, 52 | {"float_i2f", (funct_t) float_i2f, (funct_t) test_float_i2f, 1, 53 | "$", 30, 4, 54 | {{1, 1},{1,1},{1,1}}}, 55 | {"float_twice", (funct_t) float_twice, (funct_t) test_float_twice, 1, 56 | "$", 30, 4, 57 | {{1, 1},{1,1},{1,1}}}, 58 | {"", NULL, NULL, 0, "", 0, 0, 59 | {{0, 0},{0,0},{0,0}}} 60 | }; 61 | -------------------------------------------------------------------------------- /lab1-data/dlc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YeXiaoRain/ICS_LAB_CMU_2016/dbef94921745c8c4429a64943dd982e7b6e4b34a/lab1-data/dlc -------------------------------------------------------------------------------- /lab1-data/ishow.c: -------------------------------------------------------------------------------- 1 | /* Display value of fixed point numbers */ 2 | #include 3 | #include 4 | 5 | /* Extract hex/decimal/or float value from string */ 6 | static int get_num_val(char *sval, unsigned *valp) { 7 | char *endp; 8 | /* See if it's an integer or floating point */ 9 | int ishex = 0; 10 | int isfloat = 0; 11 | int i; 12 | for (i = 0; sval[i]; i++) { 13 | switch (sval[i]) { 14 | case 'x': 15 | case 'X': 16 | ishex = 1; 17 | break; 18 | case 'e': 19 | case 'E': 20 | if (!ishex) 21 | isfloat = 1; 22 | break; 23 | case '.': 24 | isfloat = 1; 25 | break; 26 | default: 27 | break; 28 | } 29 | } 30 | if (isfloat) { 31 | return 0; /* Not supposed to have a float here */ 32 | } else { 33 | long long int llval = strtoll(sval, &endp, 0); 34 | long long int upperbits = llval >> 31; 35 | /* will give -1 for negative, 0 or 1 for positive */ 36 | if (valp && (upperbits == 0 || upperbits == -1 || upperbits == 1)) { 37 | *valp = (unsigned) llval; 38 | return 1; 39 | } 40 | return 0; 41 | } 42 | } 43 | 44 | void show_int(unsigned uf) 45 | { 46 | printf("Hex = 0x%.8x,\tSigned = %d,\tUnsigned = %u\n", 47 | uf, (int) uf, uf); 48 | } 49 | 50 | 51 | void usage(char *fname) { 52 | printf("Usage: %s val1 val2 ...\n", fname); 53 | printf("Values may be given in hex or decimal\n"); 54 | exit(0); 55 | } 56 | 57 | int main(int argc, char *argv[]) 58 | { 59 | int i; 60 | unsigned uf; 61 | if (argc < 2) 62 | usage(argv[0]); 63 | for (i = 1; i < argc; i++) { 64 | char *sval = argv[i]; 65 | if (get_num_val(sval, &uf)) { 66 | show_int(uf); 67 | } else { 68 | printf("Cannot convert '%s' to 32-bit number\n", sval); 69 | } 70 | } 71 | return 0; 72 | } 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /lab1-data/tests.c: -------------------------------------------------------------------------------- 1 | /* Testing Code */ 2 | 3 | #include 4 | #include 5 | 6 | /* Routines used by floation point test code */ 7 | 8 | /* Convert from bit level representation to floating point number */ 9 | float u2f(unsigned u) { 10 | union { 11 | unsigned u; 12 | float f; 13 | } a; 14 | a.u = u; 15 | return a.f; 16 | } 17 | 18 | /* Convert from floating point number to bit-level representation */ 19 | unsigned f2u(float f) { 20 | union { 21 | unsigned u; 22 | float f; 23 | } a; 24 | a.f = f; 25 | return a.u; 26 | } 27 | 28 | int test_bitAnd(int x, int y) 29 | { 30 | return x&y; 31 | } 32 | int test_getByte(int x, int n) 33 | { 34 | unsigned char byte; 35 | switch(n) { 36 | case 0: 37 | byte = x; 38 | break; 39 | case 1: 40 | byte = x >> 8; 41 | break; 42 | case 2: 43 | byte = x >> 16; 44 | break; 45 | default: 46 | byte = x >> 24; 47 | break; 48 | } 49 | return (int) (unsigned) byte; 50 | } 51 | int test_logicalShift(int x, int n) { 52 | unsigned u = (unsigned) x; 53 | unsigned shifted = u >> n; 54 | return (int) shifted; 55 | } 56 | int test_bitCount(int x) { 57 | int result = 0; 58 | int i; 59 | for (i = 0; i < 32; i++) 60 | result += (x >> i) & 0x1; 61 | return result; 62 | } 63 | int test_bang(int x) 64 | { 65 | return !x; 66 | } 67 | int test_tmin(void) { 68 | return 0x80000000; 69 | } 70 | int test_fitsBits(int x, int n) 71 | { 72 | int TMin_n = -(1 << (n-1)); 73 | int TMax_n = (1 << (n-1)) - 1; 74 | return x >= TMin_n && x <= TMax_n; 75 | } 76 | int test_divpwr2(int x, int n) 77 | { 78 | int p2n = 1< 0; 86 | } 87 | int test_isLessOrEqual(int x, int y) 88 | { 89 | return x <= y; 90 | } 91 | int test_ilog2(int x) { 92 | int mask, result; 93 | /* find the leftmost bit */ 94 | result = 31; 95 | mask = 1 << result; 96 | while (!(x & mask)) { 97 | result--; 98 | mask = 1 << result; 99 | } 100 | return result; 101 | } 102 | unsigned test_float_neg(unsigned uf) { 103 | float f = u2f(uf); 104 | float nf = -f; 105 | if (isnan(f)) 106 | return uf; 107 | else 108 | return f2u(nf); 109 | } 110 | unsigned test_float_i2f(int x) { 111 | float f = (float) x; 112 | return f2u(f); 113 | } 114 | unsigned test_float_twice(unsigned uf) { 115 | float f = u2f(uf); 116 | float tf = 2*f; 117 | if (isnan(f)) 118 | return uf; 119 | else 120 | return f2u(tf); 121 | } 122 | -------------------------------------------------------------------------------- /lab2-bomb/README: -------------------------------------------------------------------------------- 1 | This is an x86-64 bomb for self-study students. 2 | -------------------------------------------------------------------------------- /lab2-bomb/bomb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YeXiaoRain/ICS_LAB_CMU_2016/dbef94921745c8c4429a64943dd982e7b6e4b34a/lab2-bomb/bomb -------------------------------------------------------------------------------- /lab3-buffer-32-bit/bufbomb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YeXiaoRain/ICS_LAB_CMU_2016/dbef94921745c8c4429a64943dd982e7b6e4b34a/lab3-buffer-32-bit/bufbomb -------------------------------------------------------------------------------- /lab3-buffer-32-bit/hex2raw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YeXiaoRain/ICS_LAB_CMU_2016/dbef94921745c8c4429a64943dd982e7b6e4b34a/lab3-buffer-32-bit/hex2raw -------------------------------------------------------------------------------- /lab3-buffer-32-bit/makecookie: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YeXiaoRain/ICS_LAB_CMU_2016/dbef94921745c8c4429a64943dd982e7b6e4b34a/lab3-buffer-32-bit/makecookie -------------------------------------------------------------------------------- /lab3-buffer-64-bit/README.txt: -------------------------------------------------------------------------------- 1 | This file contains materials for one instance of the attacklab. 2 | 3 | Files: 4 | 5 | ctarget 6 | 7 | Linux binary with code-injection vulnerability. To be used for phases 8 | 1-3 of the assignment. 9 | 10 | rtarget 11 | 12 | Linux binary with return-oriented programming vulnerability. To be 13 | used for phases 4-5 of the assignment. 14 | 15 | cookie.txt 16 | 17 | Text file containing 4-byte signature required for this lab instance. 18 | 19 | farm.c 20 | 21 | Source code for gadget farm present in this instance of rtarget. You 22 | can compile (use flag -Og) and disassemble it to look for gadgets. 23 | 24 | hex2raw 25 | 26 | Utility program to generate byte sequences. See documentation in lab 27 | handout. 28 | 29 | -------------------------------------------------------------------------------- /lab3-buffer-64-bit/cookie.txt: -------------------------------------------------------------------------------- 1 | 0x59b997fa 2 | -------------------------------------------------------------------------------- /lab3-buffer-64-bit/ctarget: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YeXiaoRain/ICS_LAB_CMU_2016/dbef94921745c8c4429a64943dd982e7b6e4b34a/lab3-buffer-64-bit/ctarget -------------------------------------------------------------------------------- /lab3-buffer-64-bit/hex2raw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YeXiaoRain/ICS_LAB_CMU_2016/dbef94921745c8c4429a64943dd982e7b6e4b34a/lab3-buffer-64-bit/hex2raw -------------------------------------------------------------------------------- /lab3-buffer-64-bit/rtarget: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YeXiaoRain/ICS_LAB_CMU_2016/dbef94921745c8c4429a64943dd982e7b6e4b34a/lab3-buffer-64-bit/rtarget -------------------------------------------------------------------------------- /lab4-architecture-y86-64/Makefile: -------------------------------------------------------------------------------- 1 | #################################################### 2 | # Students' Makefile for the CS:APP Architecture Lab 3 | #################################################### 4 | 5 | # Default team name and version number 6 | TEAM = bovik 7 | VERSION = 1 8 | 9 | # Where are the different parts of the lab should be copied to when they 10 | # are handed in. 11 | HANDINDIR-PARTA = /afs/cs/academic/class/15349-s02/archlab/handin-parta 12 | HANDINDIR-PARTB = /afs/cs/academic/class/15349-s02/archlab/handin-partb 13 | HANDINDIR-PARTC = /afs/cs/academic/class/15349-s02/archlab/handin-partc 14 | 15 | sim: 16 | (cd sim; make) 17 | 18 | # Use this rule to hand in Part A ("make handin-parta") 19 | handin-parta: 20 | cp sim/misc/sum.ys $(HANDINDIR-PARTA)/$(TEAM)-$(VERSION)-sum.ys 21 | cp sim/misc/rsum.ys $(HANDINDIR-PARTA)/$(TEAM)-$(VERSION)-rsum.ys 22 | cp sim/misc/copy.ys $(HANDINDIR-PARTA)/$(TEAM)-$(VERSION)-copy.ys 23 | 24 | # Use this rule to handin Part B ("make handin-partb") 25 | handin-partb: 26 | cp sim/seq/seq-full.hcl $(HANDINDIR-PARTB)/$(TEAM)-$(VERSION)-seq-full.hcl 27 | 28 | # Use this rule to handin Part C ("make handin-partc") 29 | handin-partc: 30 | cp sim/pipe/ncopy.ys $(HANDINDIR-PARTC)/$(TEAM)-$(VERSION)-ncopy.ys 31 | cp sim/pipe/pipe-full.hcl $(HANDINDIR-PARTC)/$(TEAM)-$(VERSION)-pipe-full.hcl 32 | 33 | clean: 34 | rm -f *~ *.o 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/README: -------------------------------------------------------------------------------- 1 | ##################################################################### 2 | # CS:APP Architecture Lab 3 | # Handout files for students 4 | # 5 | # Copyright (c) 2002, 2010, 2015, R. Bryant and D. O'Hallaron, 6 | # All rights reserved. May not be used, modified, or copied 7 | # without permission. 8 | # 9 | ###################################################################### 10 | 11 | This directory contains the files that you need for the CS:APP 12 | architecture lab. 13 | 14 | ****** 15 | Files: 16 | ****** 17 | 18 | Makefile Use this to handin your solutions 19 | README This file 20 | archlab.{ps,pdf} Lab writeup 21 | sim.tar Archive of the Y86-64 tools in tar format 22 | simguide.{ps,pdf} CS:APP Guide to Simulators document 23 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/archlab.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YeXiaoRain/ICS_LAB_CMU_2016/dbef94921745c8c4429a64943dd982e7b6e4b34a/lab4-architecture-y86-64/archlab.pdf -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/Makefile: -------------------------------------------------------------------------------- 1 | # Comment this out if you don't have Tcl/Tk on your system 2 | 3 | #GUIMODE=-DHAS_GUI 4 | 5 | # Modify the following line so that gcc can find the libtcl.so and 6 | # libtk.so libraries on your system. You may need to use the -L option 7 | # to tell gcc which directory to look in. Comment this out if you 8 | # don't have Tcl/Tk. 9 | 10 | TKLIBS=-L/usr/lib -ltk -ltcl 11 | 12 | # Modify the following line so that gcc can find the tcl.h and tk.h 13 | # header files on your system. Comment this out if you don't have 14 | # Tcl/Tk. 15 | 16 | TKINC=-isystem /usr/include/tcl8.5 17 | 18 | ################################################## 19 | # You shouldn't need to modify anything below here 20 | ################################################## 21 | 22 | # Use this rule (make all) to build the Y86-64 tools. The variables you've 23 | # assigned to GUIMODE, TKLIBS, and TKINC will override the values that 24 | # are currently assigned in seq/Makefile and pipe/Makefile. 25 | all: 26 | (cd misc; make all) 27 | (cd pipe; make all GUIMODE=$(GUIMODE) TKLIBS="$(TKLIBS)" TKINC="$(TKINC)") 28 | (cd seq; make all GUIMODE=$(GUIMODE) TKLIBS="$(TKLIBS)" TKINC="$(TKINC)") 29 | (cd y86-code; make all) 30 | 31 | clean: 32 | rm -f *~ core 33 | (cd misc; make clean) 34 | (cd pipe; make clean) 35 | (cd seq; make clean) 36 | (cd y86-code; make clean) 37 | (cd ptest; make clean) 38 | 39 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/misc/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | CFLAGS=-Wall -O1 -g 3 | LCFLAGS=-O1 4 | LEX = flex 5 | YACC=bison 6 | LEXLIB = -lfl 7 | YAS=./yas 8 | 9 | all: yis yas hcl2c 10 | 11 | # These are implicit rules for making .yo files from .ys files. 12 | # E.g., make sum.yo 13 | .SUFFIXES: .ys .yo 14 | .ys.yo: 15 | $(YAS) $*.ys 16 | 17 | # These are the explicit rules for making yis yas and hcl2c and hcl2v 18 | yas-grammar.o: yas-grammar.c 19 | $(CC) $(LCFLAGS) -c yas-grammar.c 20 | 21 | yas-grammar.c: yas-grammar.lex 22 | $(LEX) yas-grammar.lex 23 | mv lex.yy.c yas-grammar.c 24 | 25 | isa.o: isa.c isa.h 26 | $(CC) $(CFLAGS) -c isa.c 27 | 28 | yas.o: yas.c yas.h isa.h 29 | $(CC) $(CFLAGS) -c yas.c 30 | 31 | yas: yas.o yas-grammar.o isa.o 32 | $(CC) $(CFLAGS) yas-grammar.o yas.o isa.o ${LEXLIB} -o yas 33 | 34 | yis.o: yis.c isa.h 35 | $(CC) $(CFLAGS) -c yis.c 36 | 37 | yis: yis.o isa.o 38 | $(CC) $(CFLAGS) yis.o isa.o -o yis 39 | 40 | hcl2c: hcl.tab.c lex.yy.c node.c outgen.c 41 | $(CC) $(LCFLAGS) node.c lex.yy.c hcl.tab.c outgen.c -o hcl2c 42 | 43 | hcl2v: hcl.tab.c lex.yy.c node.c outgen.c 44 | $(CC) $(LCFLAGS) -DVLOG node.c lex.yy.c hcl.tab.c outgen.c -o hcl2v 45 | 46 | hcl2u: hcl.tab.c lex.yy.c node.c outgen.c 47 | $(CC) $(LCFLAGS) -DUCLID node.c lex.yy.c hcl.tab.c outgen.c -o hcl2u 48 | 49 | lex.yy.c: hcl.lex 50 | $(LEX) hcl.lex 51 | 52 | hcl.tab.c: hcl.y 53 | $(YACC) -d hcl.y 54 | 55 | clean: 56 | rm -f *.o *.yo *.exe yis yas hcl2c mux4 *~ core.* 57 | rm -f hcl.tab.c hcl.tab.h lex.yy.c yas-grammar.c 58 | 59 | 60 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/misc/README: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Y86-64 Assembler, Instruction Simulator, and HCL translator 3 | * 4 | * Copyright (c) 2002, R. Bryant and D. O'Hallaron, All rights reserved. 5 | * May not be used, modified, or copied without permission. 6 | ***********************************************************************/ 7 | 8 | This directory contains all of the source files for the following: 9 | 10 | YAS Y86-64 assembler 11 | YIS Y86-64 instruction level simulator 12 | HCL2C HCL to C translator 13 | HCL2V HCL to Verilog translator 14 | 15 | ********************* 16 | 1. Building the tools 17 | ********************* 18 | 19 | unix> make clean 20 | unix> make 21 | 22 | ******** 23 | 2. Files 24 | ******** 25 | 26 | Makefile Builds yas, yis, hcl2c, hcl2v 27 | README This file 28 | 29 | * Versions of Makefile in the student's distribution 30 | * (Instructor distribution only) 31 | Makefile-sim 32 | 33 | * Example programs for Part A of the CS:APP Architecture Lab 34 | examples.c C versions of three Y86-64 functions 35 | ans-copy.ys Solution copy function (instructor distribution only) 36 | ans-sum.ys Solution sum function (instructor distribution only) 37 | ans-rsum.ys Solution rsum function (instructor distribution only) 38 | 39 | 40 | * Instruction simulator code shared by yas, yis, ssim, ssim+, and psim 41 | isa.c 42 | isa.h 43 | 44 | * Files used to build the yas assembler 45 | yas The YAS binary 46 | yas.c yas source file and header file 47 | yas.h 48 | yas-grammar.lex Y86-64 lexical scanner spec 49 | yas-grammar.c Lexical scanner generated from yas-grammar.lex 50 | 51 | * Files used to build the yis instruction simulator 52 | yis The YIS binary 53 | yis.c yis source file 54 | 55 | * Files used to build the hcl2c translator 56 | hcl2c The HCL2C binary 57 | node.c auxiliary routines and header file 58 | node.h 59 | hcl.lex HCL lexical scanner spec 60 | lex.yy.c HCL lexical scanner generated from hcl.lex 61 | hcl.y HCL grammar 62 | hcl.tab.c HCL parser generated from hcl.y 63 | hcl.tab.h Token definitions 64 | 65 | * Example HCL programs used during the writing of the CS:APP book 66 | * (Instructor distribution only) 67 | frag.{hcl,c} 68 | mux4.{hcl,c} 69 | reg-file.{hcl,c} 70 | 71 | 72 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/misc/examples.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Architecture Lab: Part A 3 | * 4 | * High level specs for the functions that the students will rewrite 5 | * in Y86-64 assembly language 6 | */ 7 | 8 | /* $begin examples */ 9 | /* linked list element */ 10 | typedef struct ELE { 11 | long val; 12 | struct ELE *next; 13 | } *list_ptr; 14 | 15 | /* sum_list - Sum the elements of a linked list */ 16 | long sum_list(list_ptr ls) 17 | { 18 | long val = 0; 19 | while (ls) { 20 | val += ls->val; 21 | ls = ls->next; 22 | } 23 | return val; 24 | } 25 | 26 | /* rsum_list - Recursive version of sum_list */ 27 | long rsum_list(list_ptr ls) 28 | { 29 | if (!ls) 30 | return 0; 31 | else { 32 | long val = ls->val; 33 | long rest = rsum_list(ls->next); 34 | return val + rest; 35 | } 36 | } 37 | 38 | /* copy_block - Copy src to dest and return xor checksum of src */ 39 | long copy_block(long *src, long *dest, long len) 40 | { 41 | long result = 0; 42 | while (len > 0) { 43 | long val = *src++; 44 | *dest++ = val; 45 | result ^= val; 46 | len--; 47 | } 48 | return result; 49 | } 50 | /* $end examples */ 51 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/misc/hcl.lex: -------------------------------------------------------------------------------- 1 | %{ 2 | #include 3 | #include "node.h" 4 | #define YYSTYPE node_ptr 5 | #include "hcl.tab.h" 6 | 7 | 8 | extern YYSTYPE yylval; 9 | extern int lineno; 10 | %} 11 | %% 12 | [ \r\t\f] ; 13 | [\n] lineno++; 14 | "#".*\n lineno++ ; 15 | quote return(QUOTE); 16 | boolsig return(BOOLARG); 17 | bool return(BOOL); 18 | wordsig return(WORDARG); 19 | word return(WORD); 20 | in return(IN); 21 | '[^']*' yylval = make_quote(yytext); return(QSTRING); 22 | [a-zA-Z][a-zA-Z0-9_]* yylval = make_var(yytext); return(VAR); 23 | [0-9][0-9]* yylval = make_num(yytext); return(NUM); 24 | -[0-9][0-9]* yylval = make_num(yytext); return(NUM); 25 | "=" return(ASSIGN); 26 | ";" return(SEMI); 27 | ":" return(COLON); 28 | "," return(COMMA); 29 | "(" return(LPAREN); 30 | ")" return(RPAREN); 31 | "{" return(LBRACE); 32 | "}" return(RBRACE); 33 | "[" return(LBRACK); 34 | "]" return(RBRACK); 35 | "&&" return(AND); 36 | "||" return(OR); 37 | "!=" yylval = make_var(yytext); return(COMP); 38 | "==" yylval = make_var(yytext); return(COMP); 39 | "<" yylval = make_var(yytext); return(COMP); 40 | "<=" yylval = make_var(yytext); return(COMP); 41 | ">" yylval = make_var(yytext); return(COMP); 42 | ">=" yylval = make_var(yytext); return(COMP); 43 | "!" return(NOT); 44 | %% 45 | 46 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/misc/hcl.tab.h: -------------------------------------------------------------------------------- 1 | /* A Bison parser, made by GNU Bison 2.5. */ 2 | 3 | /* Bison interface for Yacc-like parsers in C 4 | 5 | Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc. 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . */ 19 | 20 | /* As a special exception, you may create a larger work that contains 21 | part or all of the Bison parser skeleton and distribute that work 22 | under terms of your choice, so long as that work isn't itself a 23 | parser generator using the skeleton or a modified version thereof 24 | as a parser skeleton. Alternatively, if you modify or redistribute 25 | the parser skeleton itself, you may (at your option) remove this 26 | special exception, which will cause the skeleton and the resulting 27 | Bison output files to be licensed under the GNU General Public 28 | License without this special exception. 29 | 30 | This special exception was added by the Free Software Foundation in 31 | version 2.2 of Bison. */ 32 | 33 | 34 | /* Tokens. */ 35 | #ifndef YYTOKENTYPE 36 | # define YYTOKENTYPE 37 | /* Put the tokens into the symbol table, so that GDB and other debuggers 38 | know about them. */ 39 | enum yytokentype { 40 | QUOTE = 258, 41 | BOOLARG = 259, 42 | BOOL = 260, 43 | WORDARG = 261, 44 | WORD = 262, 45 | QSTRING = 263, 46 | VAR = 264, 47 | NUM = 265, 48 | ASSIGN = 266, 49 | SEMI = 267, 50 | COLON = 268, 51 | COMMA = 269, 52 | LPAREN = 270, 53 | RPAREN = 271, 54 | LBRACE = 272, 55 | RBRACE = 273, 56 | LBRACK = 274, 57 | RBRACK = 275, 58 | AND = 276, 59 | OR = 277, 60 | NOT = 278, 61 | COMP = 279, 62 | IN = 280 63 | }; 64 | #endif 65 | 66 | 67 | 68 | #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED 69 | typedef int YYSTYPE; 70 | # define YYSTYPE_IS_TRIVIAL 1 71 | # define yystype YYSTYPE /* obsolescent; will be withdrawn */ 72 | # define YYSTYPE_IS_DECLARED 1 73 | #endif 74 | 75 | extern YYSTYPE yylval; 76 | 77 | 78 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/misc/hcl.y: -------------------------------------------------------------------------------- 1 | %{ 2 | #include 3 | #include 4 | #include 5 | #include "node.h" 6 | #define YYSTYPE node_ptr 7 | 8 | /* Current line number. Maintained by lex */ 9 | int lineno = 1; 10 | #define ERRLIM 5 11 | int errcnt = 0; 12 | 13 | 14 | 15 | FILE *outfile; 16 | 17 | int yyparse(void); 18 | int yylex(void); 19 | 20 | void yyerror(const char *str) 21 | { 22 | fprintf(stderr, "Error, near line %d: %s\n", lineno, str); 23 | if (++errcnt > ERRLIM) { 24 | fprintf(stderr, "Too many errors, aborting\n"); 25 | exit(1); 26 | } 27 | } 28 | 29 | static char errmsg[1024]; 30 | void yyserror(const char *str, char *other) 31 | { 32 | sprintf(errmsg, str, other); 33 | yyerror(errmsg); 34 | } 35 | 36 | int yywrap() 37 | { 38 | return 1; 39 | } 40 | 41 | int main(int argc, char **argv) 42 | { 43 | init_node(argc, argv); 44 | outfile = stdout; 45 | yyparse(); 46 | finish_node(0); 47 | return errcnt != 0; 48 | } 49 | 50 | %} 51 | 52 | %token QUOTE BOOLARG BOOL WORDARG WORD QSTRING 53 | VAR NUM ASSIGN SEMI COLON COMMA LPAREN RPAREN LBRACE 54 | RBRACE LBRACK RBRACK AND OR NOT COMP IN 55 | 56 | /* All operators are left associative. Listed from lowest to highest */ 57 | %left OR 58 | %left AND 59 | %left NOT 60 | %left COMP 61 | %left IN 62 | 63 | %% 64 | 65 | statements: /* empty */ 66 | | statements statement 67 | ; 68 | 69 | statement: 70 | QUOTE QSTRING { insert_code($2); } 71 | | BOOLARG VAR QSTRING { add_arg($2, $3, 1); } 72 | | WORDARG VAR QSTRING { add_arg($2, $3, 0); } 73 | | BOOL VAR ASSIGN expr SEMI { gen_funct($2, $4, 1); } 74 | | WORD VAR ASSIGN expr SEMI { gen_funct($2, $4, 0); } 75 | ; 76 | 77 | expr: 78 | VAR { $$=$1; } 79 | | NUM { $$=$1; } 80 | | LPAREN expr RPAREN { $$=$2; } 81 | | NOT expr { $$=make_not($2); } 82 | | expr AND expr { $$=make_and($1, $3); } 83 | | expr OR expr { $$=make_or($1, $3); } 84 | | expr COMP expr { $$=make_comp($2,$1,$3); } 85 | | expr IN LBRACE exprlist RBRACE { $$=make_ele($1, $4);} 86 | | LBRACK caselist RBRACK { $$=$2; } 87 | ; 88 | 89 | exprlist: 90 | expr { $$=$1; } 91 | | exprlist COMMA expr { $$=concat($1, $3); } 92 | 93 | caselist: 94 | /* Empty */ { $$=NULL; } 95 | | caselist expr COLON expr SEMI { $$=concat($1, make_case($2, $4));} 96 | 97 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/misc/mux4.hcl: -------------------------------------------------------------------------------- 1 | #/* $begin sim-mux4-raw-hcl */ 2 | ## Simple example of an HCL file. 3 | ## This file can be converted to C using hcl2c, and then compiled. 4 | 5 | ## In this example, we will generate the MUX4 circuit shown in 6 | ## Section SLASHrefLBRACKsect:arch:hclsetRBRACK. It consists of a control block that generates 7 | ## bit-level signals s1 and s0 from the input signal code, 8 | ## and then uses these signals to control a 4-way multiplexor 9 | ## with data inputs A, B, C, and D. 10 | 11 | ## This code is embedded in a C program that reads 12 | ## the values of code, A, B, C, and D from the command line 13 | ## and then prints the circuit output 14 | 15 | ## Information that is inserted verbatim into the C file 16 | quote '#include ' 17 | quote '#include ' 18 | quote 'long long code_val, s0_val, s1_val;' 19 | quote 'char **data_names;' 20 | 21 | ## Declarations of signals used in the HCL description and 22 | ## the corresponding C expressions. 23 | boolsig s0 's0_val' 24 | boolsig s1 's1_val' 25 | wordsig code 'code_val' 26 | wordsig A 'atoll(data_names[0])' 27 | wordsig B 'atoll(data_names[1])' 28 | wordsig C 'atoll(data_names[2])' 29 | wordsig D 'atoll(data_names[3])' 30 | 31 | ## HCL descriptions of the logic blocks 32 | quote '/* $begin sim-mux4-s1-c */' 33 | bool s1 = code in { 2, 3 }; 34 | quote '/* $end sim-mux4-s1-c */' 35 | 36 | bool s0 = code in { 1, 3 }; 37 | 38 | word Out4 = [ 39 | !s1 && !s0 : A; # 00 40 | !s1 : B; # 01 41 | !s0 : C; # 10 42 | 1 : D; # 11 43 | ]; 44 | 45 | ## More information inserted verbatim into the C code to 46 | ## compute the values and print the output 47 | quote '/* $begin sim-mux4-main-c */' 48 | quote 'int main(int argc, char *argv[]) {' 49 | quote ' data_names = argv+2;' 50 | quote ' code_val = atoll(argv[1]);' 51 | quote ' s1_val = gen_s1();' 52 | quote ' s0_val = gen_s0();' 53 | quote ' printf("Out = %lld\n", gen_Out4());' 54 | quote ' return 0;' 55 | quote '}' 56 | quote '/* $end sim-mux4-main-c */' 57 | #/* $end sim-mux4-raw-hcl */ 58 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/misc/node.h: -------------------------------------------------------------------------------- 1 | #ifndef NODE_H 2 | typedef enum { N_QUOTE, N_VAR, N_NUM, N_AND, N_OR, N_NOT, N_COMP, N_ELE, N_CASE } node_type_t; 3 | 4 | typedef struct NODE { 5 | node_type_t type; 6 | int isbool; /* Is this node a Boolean expression? */ 7 | char *sval; 8 | struct NODE *arg1; 9 | struct NODE *arg2; 10 | int ref; /* For var, how many times has it been referenced? */ 11 | struct NODE *next; 12 | } node_rec, *node_ptr; 13 | 14 | void init_node(int argc, char **argv); 15 | void finish_node(int check_ref); 16 | 17 | node_ptr make_quote(char *qstring); 18 | node_ptr make_var(char *name); 19 | node_ptr make_num(char *name); 20 | void set_bool(node_ptr varnode); 21 | node_ptr make_not(node_ptr arg); 22 | node_ptr make_and(node_ptr arg1, node_ptr arg2); 23 | node_ptr make_or(node_ptr arg1, node_ptr arg2); 24 | node_ptr make_comp(node_ptr op, node_ptr arg1, node_ptr arg2); 25 | node_ptr make_ele(node_ptr arg1, node_ptr arg2); 26 | node_ptr make_case(node_ptr arg1, node_ptr arg2); 27 | 28 | node_ptr concat(node_ptr n1, node_ptr n2); 29 | 30 | void insert_code(node_ptr qstring); 31 | void add_arg(node_ptr var, node_ptr qstring, int isbool); 32 | void gen_funct(node_ptr var, node_ptr expr, int isbool); 33 | #define NODE_H 34 | #endif 35 | 36 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/misc/outgen.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "outgen.h" 7 | /* Output generator that ensures no line exceeds specified number of columns */ 8 | 9 | #define STRING_LENGTH 1024 10 | 11 | FILE *outfile = NULL; 12 | int max_column = 80; 13 | int first_indent = 4; 14 | int other_indents = 2; 15 | int cur_pos = 0; 16 | int indent = 0; 17 | 18 | 19 | /* Controlling parameters */ 20 | void outgen_init(FILE *arg_outfile, int arg_max_column, int arg_first_indent, int arg_other_indents) { 21 | outfile = arg_outfile; 22 | max_column = arg_max_column; 23 | first_indent = arg_first_indent; 24 | other_indents = arg_other_indents; 25 | cur_pos = 0; 26 | indent = first_indent; 27 | } 28 | 29 | static void print_token(char *string) { 30 | if (outfile == NULL) 31 | outfile = stdout; 32 | int len = strlen(string); 33 | int i; 34 | if (len+cur_pos > max_column) { 35 | fprintf(outfile, "\n"); 36 | for (i = 0; i < indent; i++) 37 | fprintf(outfile, " "); 38 | cur_pos = indent; 39 | } 40 | fprintf(outfile, "%s", string); 41 | cur_pos += len; 42 | } 43 | 44 | 45 | /* Terminate statement and reset indentations */ 46 | void outgen_terminate() { 47 | printf("\n"); 48 | cur_pos = 0; 49 | indent = first_indent; 50 | } 51 | 52 | /* Output generator printing */ 53 | void outgen_print(char *fmt, ...) { 54 | char buf[STRING_LENGTH]; 55 | va_list argp; 56 | va_start(argp, fmt); 57 | vsprintf(buf, fmt, argp); 58 | va_end(argp); 59 | print_token(buf); 60 | } 61 | 62 | /* Increase indentation level */ 63 | void outgen_upindent() { 64 | indent += other_indents; 65 | } 66 | /* Decrease indentation level */ 67 | void outgen_downindent() { 68 | indent -= other_indents; 69 | } 70 | 71 | 72 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/misc/outgen.h: -------------------------------------------------------------------------------- 1 | /* Output generator that ensures no line exceeds specified number of columns */ 2 | 3 | /* Controlling parameters */ 4 | void outgen_init(FILE *outfile, int max_column, int first_indent, int other_indents); 5 | 6 | /* Terminate statement and reset indentations */ 7 | void outgen_terminate(); 8 | 9 | /* Output generator printing */ 10 | void outgen_print(char *fmt, ...); 11 | 12 | /* Increase indentation level */ 13 | void outgen_upindent(); 14 | /* Decrease indentation level */ 15 | void outgen_downindent(); 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/misc/yas-grammar.lex: -------------------------------------------------------------------------------- 1 | /* Grammar for Y86-64 Assembler */ 2 | #include "yas.h" 3 | 4 | Instr rrmovq|cmovle|cmovl|cmove|cmovne|cmovge|cmovg|rmmovq|mrmovq|irmovq|addq|subq|andq|xorq|jmp|jle|jl|je|jne|jge|jg|call|ret|pushq|popq|"."byte|"."word|"."long|"."quad|"."pos|"."align|halt|nop|iaddq 5 | Letter [a-zA-Z] 6 | Digit [0-9] 7 | Ident {Letter}({Letter}|{Digit}|_)* 8 | Hex [0-9a-fA-F] 9 | Blank [ \t] 10 | Newline [\n\r] 11 | Return [\r] 12 | Char [^\n\r] 13 | Reg %rax|%rcx|%rdx|%rbx|%rsi|%rdi|%rsp|%rbp|%r8|%r9|%r10|%r11|%r12|%r13|%r14 14 | 15 | %x ERR COM 16 | %% 17 | 18 | ^{Char}*{Return}*{Newline} { save_line(yytext); REJECT;} /* Snarf input line */ 19 | #{Char}*{Return}*{Newline} {finish_line(); lineno++;} 20 | "//"{Char}*{Return}*{Newline} {finish_line(); lineno++;} 21 | "/*"{Char}*{Return}*{Newline} {finish_line(); lineno++;} 22 | {Blank}*{Return}*{Newline} {finish_line(); lineno++;} 23 | 24 | {Blank}+ ; 25 | "$"+ ; 26 | {Instr} add_instr(yytext); 27 | {Reg} add_reg(yytext); 28 | [-]?{Digit}+ add_num(atoll(yytext)); 29 | "0"[xX]{Hex}+ add_num(atollh(yytext)); 30 | [():,] add_punct(*yytext); 31 | {Ident} add_ident(yytext); 32 | {Char} {; BEGIN ERR;} 33 | {Char}*{Newline} {fail("Invalid line"); lineno++; BEGIN 0;} 34 | %% 35 | 36 | unsigned int atoh(const char *s) 37 | { 38 | return(strtoul(s, NULL, 16)); 39 | } 40 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/misc/yas.h: -------------------------------------------------------------------------------- 1 | void save_line(char *); 2 | void finish_line(); 3 | void add_reg(char *); 4 | void add_ident(char *); 5 | void add_instr(char *); 6 | void add_punct(char); 7 | void add_num(long long); 8 | void fail(char *msg); 9 | unsigned long long atollh(const char *); 10 | 11 | 12 | /* Current line number */ 13 | int lineno; 14 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/misc/yis.c: -------------------------------------------------------------------------------- 1 | /* Instruction set simulator for Y86-64 Architecture */ 2 | 3 | #include 4 | #include 5 | 6 | #include "isa.h" 7 | 8 | /* YIS never runs in GUI mode */ 9 | int gui_mode = 0; 10 | 11 | void usage(char *pname) 12 | { 13 | printf("Usage: %s code_file [max_steps]\n", pname); 14 | exit(0); 15 | } 16 | 17 | int main(int argc, char *argv[]) 18 | { 19 | FILE *code_file; 20 | int max_steps = 10000; 21 | 22 | state_ptr s = new_state(MEM_SIZE); 23 | mem_t saver = copy_reg(s->r); 24 | mem_t savem; 25 | int step = 0; 26 | 27 | stat_t e = STAT_AOK; 28 | 29 | if (argc < 2 || argc > 3) 30 | usage(argv[0]); 31 | code_file = fopen(argv[1], "r"); 32 | if (!code_file) { 33 | fprintf(stderr, "Can't open code file '%s'\n", argv[1]); 34 | exit(1); 35 | } 36 | 37 | if (!load_mem(s->m, code_file, 1)) { 38 | printf("Exiting\n"); 39 | return 1; 40 | } 41 | 42 | savem = copy_mem(s->m); 43 | 44 | if (argc > 2) 45 | max_steps = atoi(argv[2]); 46 | 47 | for (step = 0; step < max_steps && e == STAT_AOK; step++) 48 | e = step_state(s, stdout); 49 | 50 | printf("Stopped in %d steps at PC = 0x%llx. Status '%s', CC %s\n", 51 | step, s->pc, stat_name(e), cc_name(s->cc)); 52 | 53 | printf("Changes to registers:\n"); 54 | diff_reg(saver, s->r, stdout); 55 | 56 | printf("\nChanges to memory:\n"); 57 | diff_mem(savem, s->m, stdout); 58 | 59 | free_state(s); 60 | free_reg(saver); 61 | free_mem(savem); 62 | 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/pipe/Makefile: -------------------------------------------------------------------------------- 1 | # Modify this line to indicate the default version to build 2 | 3 | VERSION=std 4 | 5 | # Comment this out if you don't have Tcl/Tk on your system 6 | 7 | GUIMODE=-DHAS_GUI 8 | 9 | # Modify the following line so that gcc can find the libtcl.so and 10 | # libtk.so libraries on your system. You may need to use the -L option 11 | # to tell gcc which directory to look in. Comment this out if you 12 | # don't have Tcl/Tk. 13 | 14 | TKLIBS=-L/usr/lib -ltk -ltcl 15 | 16 | # Modify the following line so that gcc can find the tcl.h and tk.h 17 | # header files on your system. Comment this out if you don't have 18 | # Tcl/Tk. 19 | 20 | TKINC=-isystem /usr/include/tcl8.5 21 | 22 | # Modify these two lines to choose your compiler and compile time 23 | # flags. 24 | 25 | CC=gcc 26 | CFLAGS=-Wall -O2 27 | 28 | ################################################## 29 | # You shouldn't need to modify anything below here 30 | ################################################## 31 | 32 | MISCDIR=../misc 33 | HCL2C=$(MISCDIR)/hcl2c 34 | INC=$(TKINC) -I$(MISCDIR) $(GUIMODE) 35 | LIBS=$(TKLIBS) -lm 36 | YAS = ../misc/yas 37 | 38 | all: psim drivers 39 | 40 | # This rule builds the PIPE simulator 41 | psim: psim.c sim.h pipe-$(VERSION).hcl $(MISCDIR)/isa.c $(MISCDIR)/isa.h 42 | # Building the pipe-$(VERSION).hcl version of PIPE 43 | $(HCL2C) -n pipe-$(VERSION).hcl < pipe-$(VERSION).hcl > pipe-$(VERSION).c 44 | $(CC) $(CFLAGS) $(INC) -o psim psim.c pipe-$(VERSION).c \ 45 | $(MISCDIR)/isa.c $(LIBS) 46 | 47 | # This rule builds driver programs for Part C of the Architecture Lab 48 | drivers: 49 | ./gen-driver.pl -n 4 -f ncopy.ys > sdriver.ys 50 | ../misc/yas sdriver.ys 51 | ./gen-driver.pl -n 63 -f ncopy.ys > ldriver.ys 52 | ../misc/yas ldriver.ys 53 | 54 | # These are implicit rules for assembling .yo files from .ys files. 55 | .SUFFIXES: .ys .yo 56 | .ys.yo: 57 | $(YAS) $*.ys 58 | 59 | 60 | clean: 61 | rm -f psim pipe-*.c *.o *.exe *~ 62 | 63 | 64 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/pipe/benchmark.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | #!/usr/local/bin/perl 3 | 4 | # 5 | # benchmark.pl - Run test of pipeline on ncopy for different block sizes 6 | # and determine CPE (cycles per element) 7 | # 8 | use Getopt::Std; 9 | 10 | # 11 | # Configuration 12 | # 13 | $blocklen = 64; 14 | $yas = "../misc/yas"; 15 | $pipe = "./psim"; 16 | $gendriver = "./gen-driver.pl"; 17 | $fname = "bdriver"; 18 | $verbose = 1; 19 | 20 | ## Grading criteria 21 | $totalpoints = 60; 22 | # What CPE is required to get full credit? 23 | $fullcpe = 7.5; 24 | # What CPE is required to get nonzero credit: 25 | $threshcpe = 10.5; 26 | 27 | 28 | 29 | # 30 | # usage - Print the help message and terminate 31 | # 32 | sub usage { 33 | print STDERR "Usage: $0 [-hq] [-n N] -f FILE\n"; 34 | print STDERR " -h Print help message\n"; 35 | print STDERR " -q Quiet mode (default verbose)\n"; 36 | print STDERR " -n N Set max number of elements up to 64 (default $blocklen)\n"; 37 | print STDERR " -f FILE Input .ys file is FILE\n"; 38 | die "\n"; 39 | } 40 | 41 | getopts('hqn:f:'); 42 | 43 | if ($opt_h) { 44 | usage(); 45 | } 46 | 47 | if ($opt_q) { 48 | $verbose = 0; 49 | } 50 | 51 | if ($opt_n) { 52 | $blocklen = $opt_n; 53 | if ($blocklen < 0 || $blocklen > 64) { 54 | print STDERR "n must be between 0 and 64\n"; 55 | die "\n"; 56 | } 57 | } 58 | 59 | # Filename is required 60 | if (!$opt_f) { 61 | $ncopy = "ncopy"; 62 | } else { 63 | $ncopy = $opt_f; 64 | # Strip off .ys 65 | $ncopy =~ s/\.ys//; 66 | } 67 | 68 | if ($verbose) { 69 | print "\t$ncopy\n"; 70 | } 71 | 72 | $tcpe = 0; 73 | for ($i = 0; $i <= $blocklen; $i++) { 74 | !(system "$gendriver -n $i -f $ncopy.ys > $fname$i.ys") || 75 | die "Couldn't generate driver file $fname$i.ys\n"; 76 | !(system "$yas $fname$i.ys") || 77 | die "Couldn't assemble file $fname$i.ys\n"; 78 | $stat = `$pipe -v 0 $fname$i.yo` || 79 | die "Couldn't simulate file $fname$i.yo\n"; 80 | !(system "rm $fname$i.ys $fname$i.yo") || 81 | die "Couldn't remove files $fname$i.ys and/or $fname$i.yo\n"; 82 | chomp $stat; 83 | $stat =~ s/[ ]*CPI:[ ]*//; 84 | $stat =~ s/ cycles.*//; 85 | if ($i > 0) { 86 | $cpe = $stat/$i; 87 | if ($verbose) { 88 | printf "%d\t%d\t%.2f\n", $i, $stat, $cpe; 89 | } 90 | $tcpe += $cpe; 91 | } else { 92 | if ($verbose) { 93 | printf "%d\t%d\n", $i, $stat; 94 | } 95 | } 96 | 97 | } 98 | 99 | $acpe = $tcpe/$blocklen; 100 | printf "Average CPE\t%.2f\n", $acpe; 101 | 102 | ## Compute Score 103 | $score = 0; 104 | if ($acpe <= $fullcpe) { 105 | $score = $totalpoints; 106 | } elsif ($acpe <= $threshcpe) { 107 | $score = $totalpoints * ($threshcpe - $acpe)/($threshcpe - $fullcpe); 108 | } 109 | printf "Score\t%.1f/%.1f\n", $score, $totalpoints; 110 | 111 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/pipe/check-len.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | # Check length of ncopy function in .yo file 4 | # Assumes that function starts with label "ncopy:" 5 | # and finishes with label "End:" 6 | 7 | $startpos = -1; 8 | $endpos = -1; 9 | 10 | while (<>) { 11 | $line = $_; 12 | if ($line =~ /(0x[0-9a-fA-F]+):.* ncopy:/) { 13 | $startpos = hex($1); 14 | } 15 | if ($line =~ /(0x[0-9a-fA-F]+):.* End:/) { 16 | $endpos = hex($1); 17 | } 18 | } 19 | 20 | if ($startpos >= 0 && $endpos > $startpos) { 21 | $len = $endpos - $startpos; 22 | print "ncopy length = $len bytes\n"; 23 | } else { 24 | print "Couldn't determine ncopy length\n"; 25 | } 26 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/pipe/ncopy.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | typedef word_t word_t; 4 | 5 | word_t src[8], dst[8]; 6 | 7 | /* $begin ncopy */ 8 | /* 9 | * ncopy - copy src to dst, returning number of positive ints 10 | * contained in src array. 11 | */ 12 | word_t ncopy(word_t *src, word_t *dst, word_t len) 13 | { 14 | word_t count = 0; 15 | word_t val; 16 | 17 | while (len > 0) { 18 | val = *src++; 19 | *dst++ = val; 20 | if (val > 0) 21 | count++; 22 | len--; 23 | } 24 | return count; 25 | } 26 | /* $end ncopy */ 27 | 28 | int main() 29 | { 30 | word_t i, count; 31 | 32 | for (i=0; i<8; i++) 33 | src[i]= i+1; 34 | count = ncopy(src, dst, 8); 35 | printf ("count=%d\n", count); 36 | exit(0); 37 | } 38 | 39 | 40 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/pipe/ncopy.ys: -------------------------------------------------------------------------------- 1 | #/* $begin ncopy-ys */ 2 | ################################################################## 3 | # ncopy.ys - Copy a src block of len words to dst. 4 | # Return the number of positive words (>0) contained in src. 5 | # 6 | # Include your name and ID here. 7 | # 8 | # Describe how and why you modified the baseline code. 9 | # 10 | ################################################################## 11 | # Do not modify this portion 12 | # Function prologue. 13 | # %rdi = src, %rsi = dst, %rdx = len 14 | ncopy: 15 | 16 | ################################################################## 17 | # You can modify this portion 18 | # Loop header 19 | xorq %rax,%rax # count = 0; 20 | andq %rdx,%rdx # len <= 0? 21 | jle Done # if so, goto Done: 22 | 23 | Loop: mrmovq (%rdi), %r10 # read val from src... 24 | rmmovq %r10, (%rsi) # ...and store it to dst 25 | andq %r10, %r10 # val <= 0? 26 | jle Npos # if so, goto Npos: 27 | irmovq $1, %r10 28 | addq %r10, %rax # count++ 29 | Npos: irmovq $1, %r10 30 | subq %r10, %rdx # len-- 31 | irmovq $8, %r10 32 | addq %r10, %rdi # src++ 33 | addq %r10, %rsi # dst++ 34 | andq %rdx,%rdx # len > 0? 35 | jg Loop # if so, goto Loop: 36 | ################################################################## 37 | # Do not modify the following section of code 38 | # Function epilogue. 39 | Done: 40 | ret 41 | ################################################################## 42 | # Keep the following label at the end of your function 43 | End: 44 | #/* $end ncopy-ys */ 45 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/pipe/pipeline.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * pipe.h 3 | * 4 | * Code for implementing pipelined processor simulators 5 | ******************************************************************************/ 6 | 7 | #ifndef PIPE_H 8 | #define PIPE_H 9 | 10 | /****************************************************************************** 11 | * #includes 12 | ******************************************************************************/ 13 | 14 | #include 15 | 16 | /****************************************************************************** 17 | * typedefs 18 | ******************************************************************************/ 19 | 20 | /* Different control operations for pipeline register */ 21 | /* LOAD: Copy next state to current */ 22 | /* STALL: Keep current state unchanged */ 23 | /* BUBBLE: Set current state to nop */ 24 | /* ERROR: Occurs when both stall & load signals set */ 25 | 26 | typedef enum { P_LOAD, P_STALL, P_BUBBLE, P_ERROR } p_stat_t; 27 | 28 | typedef struct { 29 | /* Current and next register state */ 30 | void *current; 31 | void *next; 32 | /* Contents of register when bubble occurs */ 33 | void *bubble_val; 34 | /* Number of state bytes */ 35 | int count; 36 | /* How should state be updated next time? */ 37 | p_stat_t op; 38 | } pipe_ele, *pipe_ptr; 39 | 40 | /****************************************************************************** 41 | * function declarations 42 | ******************************************************************************/ 43 | 44 | /* Create new pipe with count bytes of state */ 45 | /* bubble_val indicates state corresponding to pipeline bubble */ 46 | pipe_ptr new_pipe(int count, void *bubble_val); 47 | 48 | /* Update all pipes */ 49 | void update_pipes(); 50 | 51 | /* Set all pipes to bubble values */ 52 | void clear_pipes(); 53 | 54 | /* Utility code */ 55 | 56 | /* Print hex/oct/binary format with leading zeros */ 57 | /* bpd denotes bits per digit Should be in range 1-4, 58 | bpw denotes bits per word.*/ 59 | void wprint(uword_t x, int bpd, int bpw, FILE *fp); 60 | void wstring(uword_t x, int bpd, int bpw, char *s); 61 | 62 | /******************************************************************************/ 63 | 64 | #endif /* PIPE_H */ 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/pipe/stages.h: -------------------------------------------------------------------------------- 1 | /* 2 | * stages.h - Defines the layout of the pipe registers 3 | * Declares the functions that implement the pipeline stages 4 | */ 5 | 6 | /********** Pipeline register contents **************/ 7 | 8 | /* Program Counter */ 9 | typedef struct { 10 | word_t pc; 11 | stat_t status; 12 | } pc_ele, *pc_ptr; 13 | 14 | /* IF/ID Pipe Register */ 15 | typedef struct { 16 | byte_t icode; /* Single byte instruction code */ 17 | byte_t ifun; /* ALU/JMP qualifier */ 18 | byte_t ra; /* Register ra ID */ 19 | byte_t rb; /* Register rb ID */ 20 | word_t valc; /* Instruction word encoding immediate data */ 21 | word_t valp; /* Incremented program counter */ 22 | stat_t status; 23 | /* The following is included for debugging */ 24 | word_t stage_pc; 25 | } if_id_ele, *if_id_ptr; 26 | 27 | /* ID/EX Pipe Register */ 28 | typedef struct { 29 | byte_t icode; /* Instruction code */ 30 | byte_t ifun; /* ALU/JMP qualifier */ 31 | word_t valc; /* Immediate data */ 32 | word_t vala; /* valA */ 33 | word_t valb; /* valB */ 34 | byte_t srca; /* Source Reg ID for valA */ 35 | byte_t srcb; /* Source Reg ID for valB */ 36 | byte_t deste; /* Destination register for valE */ 37 | byte_t destm; /* Destination register for valM */ 38 | stat_t status; 39 | /* The following is included for debugging */ 40 | word_t stage_pc; 41 | } id_ex_ele, *id_ex_ptr; 42 | 43 | /* EX/MEM Pipe Register */ 44 | typedef struct { 45 | byte_t icode; /* Instruction code */ 46 | byte_t ifun; /* ALU/JMP qualifier */ 47 | bool_t takebranch; /* Taken branch signal */ 48 | word_t vale; /* valE */ 49 | word_t vala; /* valA */ 50 | byte_t deste; /* Destination register for valE */ 51 | byte_t destm; /* Destination register for valM */ 52 | byte_t srca; /* Source register for valA */ 53 | stat_t status; 54 | /* The following is included for debugging */ 55 | word_t stage_pc; 56 | } ex_mem_ele, *ex_mem_ptr; 57 | 58 | /* Mem/WB Pipe Register */ 59 | typedef struct { 60 | byte_t icode; /* Instruction code */ 61 | byte_t ifun; /* ALU/JMP qualifier */ 62 | word_t vale; /* valE */ 63 | word_t valm; /* valM */ 64 | byte_t deste; /* Destination register for valE */ 65 | byte_t destm; /* Destination register for valM */ 66 | stat_t status; 67 | /* The following is included for debugging */ 68 | word_t stage_pc; 69 | } mem_wb_ele, *mem_wb_ptr; 70 | 71 | /************ Global Declarations ********************/ 72 | 73 | extern pc_ele bubble_pc; 74 | extern if_id_ele bubble_if_id; 75 | extern id_ex_ele bubble_id_ex; 76 | extern ex_mem_ele bubble_ex_mem; 77 | extern mem_wb_ele bubble_mem_wb; 78 | 79 | /************ Function declarations *******************/ 80 | 81 | /* Stage functions */ 82 | void do_if_stage(); 83 | void do_id_wb_stages(); /* Both ID and WB */ 84 | void do_ex_stage(); 85 | void do_mem_stage(); 86 | 87 | /* Set stalling conditions for different stages */ 88 | void do_stall_check(); 89 | 90 | 91 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/ptest/Makefile: -------------------------------------------------------------------------------- 1 | SIM=../pipe/psim 2 | TFLAGS= 3 | 4 | ISADIR = ../misc 5 | YAS=$(ISADIR)/yas 6 | 7 | .SUFFIXES: .ys .yo 8 | 9 | .ys.yo: 10 | $(YAS) $*.ys 11 | 12 | test: 13 | ./optest.pl -s $(SIM) $(TFLAGS) 14 | ./jtest.pl -s $(SIM) $(TFLAGS) 15 | ./ctest.pl -s $(SIM) $(TFLAGS) 16 | ./htest.pl -s $(SIM) $(TFLAGS) 17 | 18 | clean: 19 | rm -f *.o *~ *.yo *.ys 20 | 21 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/ptest/README: -------------------------------------------------------------------------------- 1 | This directory contains Perl scripts that provide comprehensive 2 | regression testing of the different Y86-64 simulators. There are four 3 | basic test types, implemented as four different scripts: 4 | 5 | optest.pl: Tests each individual instruction type 6 | jtest.pl: Tests all of the jump types under different conditions 7 | ctest.pl: Tests different pipeline control combinations 8 | htest.pl: Tests many different hazard possibilities 9 | This involves running 864+ tests, so it takes a while. 10 | 11 | Each of the tests has the following optional arguments: 12 | -s simfile Use simfile as simulator (default ../pipe/psim). 13 | -i Test the iaddq instruction 14 | 15 | You can use make to run all four test programs. Options to make include: 16 | 17 | SIM=simfile 18 | TFLAGS= 19 | 20 | For example, you could say: 21 | make SIM=../pipe/psim TFLAGS=-i 22 | to test the pipeline simulator including the iaddq instruction. (Note that 23 | this test will fail for the default implementation of pipe, since it does 24 | not implement the iaddq instruction.) 25 | 26 | When the test program detects an erroneous simulation, it leaves the 27 | .ys file in the directory (ordinarily it deletes the test code it 28 | generates). You can then run a simulator (the GUI version is 29 | especially helpful here) on one of these failing cases. Suppose the 30 | failing test is in file bad-test.ys. Then you can execute "make 31 | bad-test.yo" to create the object code, and simulate it with one of 32 | the simulators. 33 | 34 | Note that the standard test code only detects functional bugs, where the 35 | processor simulation produces different results than would be 36 | predicted by simulating at the ISA level. 37 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/ptest/ctest.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | #!/usr/local/bin/perl 3 | # Test for pipeline hazard combinations 4 | 5 | use Getopt::Std; 6 | use lib "."; 7 | use tester; 8 | 9 | cmdline(); 10 | 11 | # Instruction templates 12 | $tcount = 8; 13 | 14 | @templates = 15 | ( 16 | "||jne target\n\thalt\ntarget:|", # M 17 | "|||ret", # R 18 | 19 | "||mrmovq (%rax),%rsp|ret", # G1a 20 | "|mrmovq (%rax),%rsp||ret", # G1b 21 | "mrmovq (%rax),%rsp|||ret", # G1c 22 | "||irmovq \$3,%rax|rrmovq %rax,%rdx", # G2a 23 | "|irmovq \$3,%rax||rrmovq %rax,%rdx", # G2b 24 | "irmovq \$3,%rax|||rrmovq %rax,%rdx", # G2c 25 | ); 26 | 27 | # Try combining two templates to generate test sequence 28 | sub make_test 29 | { 30 | local ($t1, $t2) = @_; 31 | $ok = 1; 32 | @test1 = split(/\|/, $t1); 33 | @test2 = split(/\|/, $t2); 34 | for ($i = 0; $i < 4; $i++) { 35 | if ($test1[$i] eq "") { 36 | if ($test2[$i] eq "") { 37 | $test[$i] = "nop"; 38 | } else { 39 | $test[$i] = $test2[$i]; 40 | } 41 | } else { 42 | if ($test2[$i] eq "") { 43 | $test[$i] = $test1[$i]; 44 | } else { 45 | if ($test1[$i] eq $test2[$i]) { 46 | # $ok = 0; 47 | $test[$i] = $test1[$i]; 48 | } else { 49 | $ok = 0; 50 | $test[$i] = "XXX"; 51 | } 52 | } 53 | } 54 | } 55 | if ($ok) { 56 | &gen_test($test[0], $test[1], $test[2], $test[3]); 57 | } 58 | 59 | } 60 | 61 | $testcnt = 0; 62 | 63 | # Generate test with 4 instructions inserted 64 | sub gen_test 65 | { 66 | local ($i1, $i2, $i3, $i4) = @_; 67 | $tname = "c-$testcnt"; 68 | $testcnt++; 69 | open(YFILE, ">$tname.ys") || die "Can't write to $tname.ys\n"; 70 | 71 | print YFILE <$tname.ys") || die "Can't write to $tname.ys\n"; 59 | &gen_test($e, "nop", $s); 60 | close YFILE; 61 | &run_test($tname); 62 | 63 | # Two instructions in succession 64 | $tname = "e-$ei-$si"; 65 | open (YFILE, ">$tname.ys") || die "Can't write to $tname.ys\n"; 66 | &gen_test($e, "", $s); 67 | close YFILE; 68 | &run_test($tname); 69 | $si++; 70 | } 71 | $si = 0; 72 | $ei++; 73 | } 74 | 75 | &test_stat(); 76 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/ptest/jtest.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | #!/usr/local/bin/perl 3 | # Test jump instructions 4 | 5 | use Getopt::Std; 6 | use lib "."; 7 | use tester; 8 | 9 | cmdline(); 10 | 11 | @vals = (32, 64); 12 | 13 | @instr = ("jmp", "jle", "jl", "je", "jne", "jge", "jg", "call"); 14 | 15 | # Create set of forward tests 16 | foreach $t (@instr) { 17 | foreach $va (@vals) { 18 | foreach $vb (@vals) { 19 | $tname = "jf-$t-$va-$vb"; 20 | open (YFILE, ">$tname.ys") || die "Can't write to $tname.ys\n"; 21 | print YFILE <$tname.ys") || die "Can't write to $tname.ys\n"; 56 | print YFILE <$tname.ys") || die "Can't write to $tname.ys\n"; 96 | print YFILE <$tname.ys") || die "Can't write to $tname.ys\n"; 21 | print YFILE <$tname.ys") || die "Can't write to $tname.ys\n"; 43 | print YFILE <$tname.ys") || die "Can't write to $tname.ys\n"; 66 | print YFILE <seq-$(VERSION).c 44 | $(CC) $(CFLAGS) $(INC) -o ssim \ 45 | seq-$(VERSION).c ssim.c $(MISCDIR)/isa.c $(LIBS) 46 | 47 | # This rule builds the SEQ+ simulator (ssim+) 48 | ssim+: seq+-std.hcl ssim.c sim.h $(MISCDIR)/isa.c $(MISCDIR)/isa.h 49 | # Building the seq+-std.hcl version of SEQ+ 50 | $(HCL2C) -n seq+-std.hcl seq+-std.c 51 | $(CC) $(CFLAGS) $(INC) -o ssim+ \ 52 | seq+-std.c ssim.c $(MISCDIR)/isa.c $(LIBS) 53 | 54 | # These are implicit rules for assembling .yo files from .ys files. 55 | .SUFFIXES: .ys .yo 56 | .ys.yo: 57 | $(YAS) $*.ys 58 | 59 | 60 | clean: 61 | rm -f ssim ssim+ seq*-*.c *.o *~ *.exe *.yo *.ys 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/seq/sim.h: -------------------------------------------------------------------------------- 1 | 2 | /********** Defines **************/ 3 | 4 | /* Get ra out of one byte regid field */ 5 | #define GET_RA(r) HI4(r) 6 | 7 | /* Get rb out of one byte regid field */ 8 | #define GET_RB(r) LO4(r) 9 | 10 | 11 | /************ Global state declaration ****************/ 12 | 13 | /* Determines whether running SEQ or SEQ+ */ 14 | extern int plusmode; 15 | 16 | /* Both instruction and data memory */ 17 | extern mem_t mem; 18 | 19 | /* Keep track of range of addresses that have been written */ 20 | extern word_t minAddr; 21 | extern word_t memCnt; 22 | 23 | /* Register file */ 24 | extern mem_t reg; 25 | /* Condition code register */ 26 | extern cc_t cc; 27 | /* Program counter */ 28 | extern word_t pc; 29 | 30 | /* For seq+ */ 31 | /* Results computed by previous instruction. 32 | Used to compute PC in current instruction */ 33 | extern byte_t prev_icode; 34 | extern byte_t prev_ifun; 35 | extern word_t prev_valc; 36 | extern word_t prev_valm; 37 | extern word_t prev_valp; 38 | extern bool_t prev_bcond; 39 | 40 | /* Intermdiate stage values that must be used by control functions */ 41 | extern byte_t imem_icode; 42 | extern byte_t imem_ifun; 43 | extern byte_t icode; 44 | extern word_t ifun; 45 | extern word_t ra; 46 | extern word_t rb; 47 | extern word_t valc; 48 | extern word_t valp; 49 | extern bool_t imem_error; 50 | extern bool_t instr_valid; 51 | extern word_t vala; 52 | extern word_t valb; 53 | extern word_t vale; 54 | extern bool_t bcond; 55 | extern bool_t cond; 56 | extern word_t valm; 57 | extern bool_t dmem_error; 58 | extern byte_t status; 59 | 60 | /* Log file */ 61 | extern FILE *dumpfile; 62 | 63 | 64 | /* Sets the simulator name (called from main routine in HCL file) */ 65 | void set_simname(char *name); 66 | 67 | /* Initialize simulator */ 68 | void sim_init(); 69 | 70 | /* Reset simulator state, including register, instruction, and data memories */ 71 | void sim_reset(); 72 | 73 | /* 74 | Run processor until one of following occurs: 75 | - An status error is encountered 76 | - max_instr instructions have completed 77 | 78 | Return number of instructions executed. 79 | if statusp nonnull, then will be set to status of final instruction 80 | if ccp nonnull, then will be set to condition codes of final instruction 81 | */ 82 | word_t sim_run(word_t max_instr, byte_t *statusp, cc_t *ccp); 83 | 84 | /* If dumpfile set nonNULL, lots of status info printed out */ 85 | void sim_set_dumpfile(FILE *file); 86 | 87 | /* 88 | * sim_log dumps a formatted string to the dumpfile, if it exists 89 | * accepts variable argument list 90 | */ 91 | void sim_log( const char *format, ... ); 92 | 93 | 94 | /******************* GUI Interface Functions **********************/ 95 | #ifdef HAS_GUI 96 | 97 | void signal_register_clear(); 98 | 99 | void report_pc(word_t pc); 100 | 101 | void report_state(char *id, char *txt); 102 | 103 | void show_cc(cc_t cc); 104 | 105 | void create_memory_display(); 106 | void set_memory(word_t addr, word_t val); 107 | #endif 108 | 109 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/y86-code/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | CFLAGS=-Wall -O2 3 | 4 | ISADIR = ../misc 5 | YAS=$(ISADIR)/yas 6 | YIS=$(ISADIR)/yis 7 | PIPE=../pipe/psim 8 | SEQ=../seq/ssim 9 | SEQ+ =../seq/ssim+ 10 | 11 | YOFILES = abs-asum-cmov.yo abs-asum-jmp.yo asum.yo asumr.yo asumi.yo cjr.yo j-cc.yo poptest.yo pushquestion.yo pushtest.yo prog1.yo prog2.yo prog3.yo prog4.yo prog5.yo prog6.yo prog7.yo prog8.yo prog9.yo prog10.yo ret-hazard.yo 12 | 13 | PIPEFILES = asum.pipe asumr.pipe cjr.pipe j-cc.pipe poptest.pipe pushquestion.pipe pushtest.pipe prog1.pipe prog2.pipe prog3.pipe prog4.pipe prog5.pipe prog6.pipe prog7.pipe prog8.pipe ret-hazard.pipe 14 | 15 | SEQFILES = asum.seq asumr.seq cjr.seq j-cc.seq poptest.seq pushquestion.seq pushtest.seq prog1.seq prog2.seq prog3.seq prog4.seq prog5.seq prog6.seq prog7.seq prog8.seq ret-hazard.seq 16 | 17 | SEQ+FILES = asum.seq+ asumr.seq+ cjr.seq+ j-cc.seq+ poptest.seq+ pushquestion.seq+ pushtest.seq+ prog1.seq+ prog2.seq+ prog3.seq+ prog4.seq+ prog5.seq+ prog6.seq+ prog7.seq+ prog8.seq+ ret-hazard.seq+ 18 | 19 | .SUFFIXES: 20 | .SUFFIXES: .c .s .o .ys .yo .yis .pipe .seq .seq+ 21 | 22 | all: $(YOFILES) 23 | 24 | test: testpsim testssim testssim+ 25 | 26 | testpsim: $(PIPEFILES) 27 | grep "ISA Check" *.pipe 28 | rm $(PIPEFILES) 29 | 30 | testssim: $(SEQFILES) 31 | grep "ISA Check" *.seq 32 | rm $(SEQFILES) 33 | 34 | testssim+: $(SEQ+FILES) 35 | grep "ISA Check" *.seq+ 36 | rm $(SEQ+FILES) 37 | 38 | .ys.yo: 39 | $(YAS) $*.ys 40 | 41 | .yo.yis: $(YIS) 42 | $(YIS) $*.yo > $*.yis 43 | 44 | .yo.pipe: $(PIPE) 45 | $(PIPE) -t $*.yo > $*.pipe 46 | 47 | .yo.seq: $(SEQ) 48 | $(SEQ) -t $*.yo > $*.seq 49 | 50 | .yo.seq+: $(SEQ+) 51 | $(SEQ+) -t $*.yo > $*.seq+ 52 | 53 | clean: 54 | rm -f *.o *.yis *~ *.yo *.pipe *.seq *.seq+ core 55 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/y86-code/README: -------------------------------------------------------------------------------- 1 | This directory contains examples of Y86-64 assembly code programs 2 | (extension `.ys') used in Chapter 4 of CS:APP3e. 3 | 4 | Given an assembly code file "file.ys", you can assemble it with the 5 | command "make file.yo". The resulting file is in the "object code" 6 | format described in the book. 7 | 8 | You can assemble and simulate all the test programs in this directory. 9 | First, you need to make the different simulators in the pipe (psim) 10 | and seq (ssim and ssim+) directories. Then use the following 11 | commands: 12 | 13 | PIPE: make testpsim 14 | SEQ: make testssim 15 | SEQ+: make testssim+ 16 | 17 | Each of these commands will cause a number of programs to be assembled 18 | and simulated. Lots of things will scroll by, but you should see the message 19 | "ISA Check Succeeds" for each of the programs tested. 20 | 21 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/y86-code/abs-asum-cmov.ys: -------------------------------------------------------------------------------- 1 | # Modification of asum code to compute absolute values of entries. 2 | # This version uses a conditional move 3 | # Execution begins at address 0 4 | .pos 0 5 | irmovq stack, %rsp # Set up stack pointer 6 | call main # Execute main program 7 | halt # Terminate program 8 | 9 | # Array of 4 elements 10 | .align 8 11 | array: .quad 0x0000000d000d000d 12 | .quad 0xffffff3fff3fff40 # -0x000000c000c000c0 13 | .quad 0x00000b000b000b00 14 | .quad 0xffff5fff5fff6000 # -0x0000a000a000a000 15 | 16 | main: 17 | irmovq array,%rdi 18 | irmovq $4,%rsi 19 | call absSum # absSum(array, 4) 20 | ret 21 | 22 | # long absSum(long *start, long count) 23 | # start in %rdi, count in %rsi 24 | absSum: 25 | irmovq $8,%r8 # Constant 8 26 | irmovq $1,%r9 # Constant 1 27 | xorq %rax,%rax # sum = 0 28 | andq %rsi,%rsi # Set condition codes 29 | jmp test 30 | /* $begin abs-sum-cmov-ys */ 31 | loop: 32 | mrmovq (%rdi),%r10 # x = *start 33 | xorq %r11,%r11 # Constant 0 34 | subq %r10,%r11 # -x 35 | cmovg %r11,%r10 # If -x > 0 then x = -x 36 | addq %r10,%rax # Add to sum 37 | addq %r8,%rdi # start++ 38 | subq %r9,%rsi # count-- 39 | test: 40 | jne loop # Stop when 0 41 | /* $end abs-sum-cmov-ys */ 42 | ret 43 | 44 | # The stack starts here and grows to lower addresses 45 | .pos 0x200 46 | stack: 47 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/y86-code/abs-asum-jmp.ys: -------------------------------------------------------------------------------- 1 | # Modification of asum code to compute absolute values of entries. 2 | # This version uses a conditional jump 3 | # Execution begins at address 0 4 | .pos 0 5 | irmovq stack, %rsp # Set up stack pointer 6 | call main # Execute main program 7 | halt # Terminate program 8 | 9 | # Array of 4 elements 10 | .align 8 11 | array: .quad 0x0000000d000d000d 12 | .quad 0xffffff3fff3fff40 # -0x000000c000c000c0 13 | .quad 0x00000b000b000b00 14 | .quad 0xffff5fff5fff6000 # -0x0000a000a000a000 15 | 16 | main: irmovq array,%rdi 17 | irmovq $4,%rsi 18 | call absSum # absSum(array, 4) 19 | ret 20 | /* $begin abs-sum-jmp-ys */ 21 | # long absSum(long *start, long count) 22 | # start in %rdi, count in %rsi 23 | absSum: 24 | irmovq $8,%r8 # Constant 8 25 | irmovq $1,%r9 # Constant 1 26 | xorq %rax,%rax # sum = 0 27 | andq %rsi,%rsi # Set condition codes 28 | jmp test 29 | loop: 30 | mrmovq (%rdi),%r10 # x = *start 31 | xorq %r11,%r11 # Constant 0 32 | subq %r10,%r11 # -x 33 | jle pos # Skip if -x <= 0 34 | rrmovq %r11,%r10 # x = -x 35 | pos: 36 | addq %r10,%rax # Add to sum 37 | addq %r8,%rdi # start++ 38 | subq %r9,%rsi # count-- 39 | test: 40 | jne loop # Stop when 0 41 | ret 42 | /* $end abs-sum-jmp-ys */ 43 | 44 | # The stack starts here and grows to lower addresses 45 | .pos 0x200 46 | stack: 47 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/y86-code/asum.ys: -------------------------------------------------------------------------------- 1 | # Execution begins at address 0 2 | .pos 0 3 | irmovq stack, %rsp # Set up stack pointer 4 | call main # Execute main program 5 | halt # Terminate program 6 | 7 | # Array of 4 elements 8 | .align 8 9 | array: .quad 0x000d000d000d 10 | .quad 0x00c000c000c0 11 | .quad 0x0b000b000b00 12 | .quad 0xa000a000a000 13 | 14 | main: irmovq array,%rdi 15 | irmovq $4,%rsi 16 | call sum # sum(array, 4) 17 | ret 18 | 19 | # long sum(long *start, long count) 20 | # start in %rdi, count in %rsi 21 | sum: irmovq $8,%r8 # Constant 8 22 | irmovq $1,%r9 # Constant 1 23 | xorq %rax,%rax # sum = 0 24 | andq %rsi,%rsi # Set CC 25 | jmp test # Goto test 26 | loop: mrmovq (%rdi),%r10 # Get *start 27 | addq %r10,%rax # Add to sum 28 | addq %r8,%rdi # start++ 29 | subq %r9,%rsi # count--. Set CC 30 | test: jne loop # Stop when 0 31 | ret # Return 32 | 33 | # Stack starts here and grows to lower addresses 34 | .pos 0x200 35 | stack: 36 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/y86-code/asumi.ys: -------------------------------------------------------------------------------- 1 | # Execution begins at address 0 2 | .pos 0 3 | irmovq stack, %rsp # Set up stack pointer 4 | call main # Execute main program 5 | halt # Terminate program 6 | 7 | # Array of 4 elements 8 | .align 8 9 | array: .quad 0x000d000d000d 10 | .quad 0x00c000c000c0 11 | .quad 0x0b000b000b00 12 | .quad 0xa000a000a000 13 | 14 | main: irmovq array,%rdi 15 | irmovq $4,%rsi 16 | call sum # sum(array, 4) 17 | ret 18 | 19 | /* $begin sumi-ys */ 20 | # long sum(long *start, long count) 21 | # start in %rdi, count in %rsi 22 | sum: 23 | xorq %rax,%rax # sum = 0 24 | andq %rsi,%rsi # Set condition codes 25 | jmp test 26 | loop: 27 | mrmovq (%rdi),%r10 # Get *start 28 | addq %r10,%rax # Add to sum 29 | iaddq $8,%rdi # start++ 30 | iaddq $-1,%rsi # count-- 31 | test: 32 | jne loop # Stop when 0 33 | ret 34 | /* $end sumi-ys */ 35 | 36 | # The stack starts here and grows to lower addresses 37 | .pos 0x100 38 | stack: 39 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/y86-code/asumr.ys: -------------------------------------------------------------------------------- 1 | # Execution begins at address 0 2 | .pos 0 3 | irmovq stack, %rsp # Set up stack pointer 4 | call main # Execute main program 5 | halt # Terminate program 6 | 7 | # Array of 4 elements 8 | .align 8 9 | array: .quad 0x000d000d000d 10 | .quad 0x00c000c000c0 11 | .quad 0x0b000b000b00 12 | .quad 0xa000a000a000 13 | 14 | main: irmovq array,%rdi 15 | irmovq $4,%rsi 16 | call rsum # rsum(array, 4) 17 | ret 18 | 19 | /* $begin rsum-ys */ 20 | # long rsum(long *start, long count) 21 | # start in %rdi, count in %rsi 22 | rsum: 23 | xorq %rax,%rax # Set return value to 0 24 | andq %rsi,%rsi # Set condition codes 25 | jle return # If count <= 0, return 0 26 | pushq %rbx # Save callee-saved register 27 | mrmovq (%rdi),%rbx # Get *start 28 | irmovq $-1,%r10 29 | addq %r10,%rsi # count-- 30 | irmovq $8,%r10 31 | addq %r10,%rdi # start++ 32 | call rsum 33 | addq %rbx,%rax # Add *start to sum 34 | popq %rbx # Restore callee-saved register 35 | return: 36 | ret 37 | /* $end rsum-ys */ 38 | 39 | # The stack starts here and grows to lower addresses 40 | .pos 0x200 41 | stack: 42 | 43 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/y86-code/cjr.ys: -------------------------------------------------------------------------------- 1 | # /* $begin cjr-ys */ 2 | # Code to generate a combination of not-taken branch and ret 3 | irmovq Stack, %rsp 4 | irmovq rtnp,%rax 5 | pushq %rax # Set up return pointer 6 | xorq %rax,%rax # Set Z condition code 7 | jne target # Not taken (First part of combination) 8 | irmovq $1,%rax # Should execute this 9 | halt 10 | target: ret # Second part of combination 11 | irmovq $2,%rbx # Should not execute this 12 | halt 13 | rtnp: irmovq $3,%rdx # Should not execute this 14 | halt 15 | .pos 0x40 16 | Stack: 17 | # /* $end cjr-ys */ 18 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/y86-code/j-cc.ys: -------------------------------------------------------------------------------- 1 | irmovq $1, %rsi 2 | irmovq $2, %rdi 3 | irmovq $4, %rbp 4 | irmovq $-32, %rax 5 | irmovq $64, %rdx 6 | subq %rdx,%rax 7 | je target 8 | nop 9 | halt 10 | target: 11 | addq %rsi,%rdx 12 | nop 13 | nop 14 | nop 15 | halt 16 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/y86-code/poptest.ys: -------------------------------------------------------------------------------- 1 | # Test of Pop semantics for Y86-64 2 | irmovq $0x100,%rsp # Initialize stack pointer 3 | irmovq $0xABCD,%rax 4 | pushq %rax # Put known value on stack 5 | popq %rsp # Either get 0xABCD, or 0xfc 6 | halt 7 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/y86-code/prog1.ys: -------------------------------------------------------------------------------- 1 | # prog1: Pad with 3 nop's 2 | irmovq $10,%rdx 3 | irmovq $3,%rax 4 | nop 5 | nop 6 | nop 7 | addq %rdx,%rax 8 | halt 9 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/y86-code/prog10.ys: -------------------------------------------------------------------------------- 1 | # prog10 2 | irmovq $1,%rax 3 | xorq %rsp,%rsp # Set stack pointer to 0 and CC to 100 4 | pushq %rax # Attempt to write to 0xfffffffffffffff8 5 | addq %rax,%rax # (Should not be executed) Would set CC to 000 6 | irmovq $2, %rax # Not executed 7 | irmovq $3, %rax # Not executed 8 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/y86-code/prog2.ys: -------------------------------------------------------------------------------- 1 | # prog2: Pad with 2 nop's 2 | irmovq $10,%rdx 3 | irmovq $3,%rax 4 | nop 5 | nop 6 | addq %rdx,%rax 7 | halt 8 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/y86-code/prog3.ys: -------------------------------------------------------------------------------- 1 | # prog3: Pad with 1 nop 2 | irmovq $10,%rdx 3 | irmovq $3,%rax 4 | nop 5 | addq %rdx,%rax 6 | halt 7 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/y86-code/prog4.ys: -------------------------------------------------------------------------------- 1 | # prog4: No padding 2 | irmovq $10,%rdx 3 | irmovq $3,%rax 4 | addq %rdx,%rax 5 | halt 6 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/y86-code/prog5.ys: -------------------------------------------------------------------------------- 1 | # prog5: Load/use hazard 2 | irmovq $128,%rdx 3 | irmovq $3,%rcx 4 | rmmovq %rcx, 0(%rdx) 5 | irmovq $10,%rbx 6 | mrmovq 0(%rdx), %rax # Load %rax 7 | addq %rbx,%rax # Use %rax 8 | halt 9 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/y86-code/prog6.ys: -------------------------------------------------------------------------------- 1 | # Demonstration of return 2 | # /* $begin prog6-ys */ 3 | # prog6 4 | irmovq stack,%rsp # Initialize stack pointer 5 | call proc # Procedure call 6 | irmovq $10,%rdx # Return point 7 | halt 8 | .pos 0x20 9 | proc: # proc: 10 | ret # Return immediately 11 | rrmovq %rdx,%rbx # Not executed 12 | .pos 0x30 13 | stack: # stack: Stack pointer 14 | # /* $end prog6-ys */ 15 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/y86-code/prog7.ys: -------------------------------------------------------------------------------- 1 | # Demonstrate branch cancellation 2 | # /* $begin prog7-ys */ 3 | # prog7 4 | xorq %rax,%rax 5 | jne target # Not taken 6 | irmovq $1, %rax # Fall through 7 | halt 8 | target: 9 | irmovq $2, %rdx # Target 10 | irmovq $3, %rbx # Target+1 11 | # /* $end prog7-ys */ 12 | halt 13 | 14 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/y86-code/prog8.ys: -------------------------------------------------------------------------------- 1 | # prog8: Forwarding Priority 2 | irmovq $10,%rdx 3 | irmovq $3,%rdx 4 | rrmovq %rdx,%rax 5 | halt 6 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/y86-code/prog9.ys: -------------------------------------------------------------------------------- 1 | # Exception handling 2 | # /* $begin prog9-yo */ 3 | xorq %rax,%rax 4 | jne target # Not taken 5 | irmovq $1, %rax # Fall through 6 | halt 7 | target: 8 | .byte 0xFF # Invalid instruction code 9 | # /* $end prog9-yo */ 10 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/y86-code/pushquestion.ys: -------------------------------------------------------------------------------- 1 | # Assembly Code to test semantics of pushq 2 | irmovq 0x100, %rsp 3 | pushq %rsp # Ambiguous 4 | popq %rax 5 | halt 6 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/y86-code/pushtest.ys: -------------------------------------------------------------------------------- 1 | # Test of Push semantics for Y86-64 2 | irmovq $0x100,%rsp # Initialize stack pointer 3 | rrmovq %rsp,%rax # Save stack pointer 4 | pushq %rsp # Push the stack pointer (old or new?) 5 | popq %rdx # Get it back 6 | subq %rdx,%rax # Compute difference. Either 0 (old) or 4 (new). 7 | halt 8 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/sim/y86-code/ret-hazard.ys: -------------------------------------------------------------------------------- 1 | /* $begin ret-hazard-ys */ 2 | # Test instruction that modifies %esp followed by ret 3 | irmovq mem,%rbx 4 | mrmovq 0(%rbx),%rsp # Sets %rsp to point to return point 5 | ret # Returns to return point 6 | halt # 7 | rtnpt: irmovq $5,%rsi # Return point 8 | halt 9 | .pos 0x40 10 | mem: .quad stack # Holds desired stack pointer 11 | .pos 0x50 12 | stack: .quad rtnpt # Top of stack: Holds return point 13 | /* $end ret-hazard-ys */ 14 | -------------------------------------------------------------------------------- /lab4-architecture-y86-64/simguide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YeXiaoRain/ICS_LAB_CMU_2016/dbef94921745c8c4429a64943dd982e7b6e4b34a/lab4-architecture-y86-64/simguide.pdf -------------------------------------------------------------------------------- /lab4-architecture-y86/Makefile: -------------------------------------------------------------------------------- 1 | #################################################### 2 | # Students' Makefile for the CS:APP Architecture Lab 3 | #################################################### 4 | 5 | # Default team name and version number 6 | TEAM = bovik 7 | VERSION = 1 8 | 9 | # Where are the different parts of the lab should be copied to when they 10 | # are handed in. 11 | HANDINDIR-PARTA = /afs/cs/academic/class/15349-s02/archlab/handin-parta 12 | HANDINDIR-PARTB = /afs/cs/academic/class/15349-s02/archlab/handin-partb 13 | HANDINDIR-PARTC = /afs/cs/academic/class/15349-s02/archlab/handin-partc 14 | 15 | sim: 16 | (cd sim; make) 17 | 18 | # Use this rule to hand in Part A ("make handin-parta") 19 | handin-parta: 20 | cp sim/misc/sum.ys $(HANDINDIR-PARTA)/$(TEAM)-$(VERSION)-sum.ys 21 | cp sim/misc/rsum.ys $(HANDINDIR-PARTA)/$(TEAM)-$(VERSION)-rsum.ys 22 | cp sim/misc/copy.ys $(HANDINDIR-PARTA)/$(TEAM)-$(VERSION)-copy.ys 23 | 24 | # Use this rule to handin Part B ("make handin-partb") 25 | handin-partb: 26 | cp sim/seq/seq-full.hcl $(HANDINDIR-PARTB)/$(TEAM)-$(VERSION)-seq-full.hcl 27 | 28 | # Use this rule to handin Part C ("make handin-partc") 29 | handin-partc: 30 | cp sim/pipe/ncopy.ys $(HANDINDIR-PARTC)/$(TEAM)-$(VERSION)-ncopy.ys 31 | cp sim/pipe/pipe-full.hcl $(HANDINDIR-PARTC)/$(TEAM)-$(VERSION)-pipe-full.hcl 32 | 33 | clean: 34 | rm -f *~ *.o 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /lab4-architecture-y86/README: -------------------------------------------------------------------------------- 1 | ##################################################################### 2 | # CS:APP Architecture Lab 3 | # Handout files for students 4 | # 5 | # Copyright (c) 2002, 2010 R. Bryant and D. O'Hallaron, 6 | # All rights reserved. May not be used, modified, or copied 7 | # without permission. 8 | # 9 | ###################################################################### 10 | 11 | This directory contains the files that you need for the CS:APP 12 | architecture lab. 13 | 14 | ****** 15 | Files: 16 | ****** 17 | 18 | Makefile Use this to handin your solutions 19 | README This file 20 | archlab.{ps,pdf} Lab writeup 21 | sim.tar Archive of the Y86 tools in tar format 22 | simguide.{ps,pdf} CS:APP Guide to Simulators document 23 | -------------------------------------------------------------------------------- /lab4-architecture-y86/archlab.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YeXiaoRain/ICS_LAB_CMU_2016/dbef94921745c8c4429a64943dd982e7b6e4b34a/lab4-architecture-y86/archlab.pdf -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/Makefile: -------------------------------------------------------------------------------- 1 | # Comment this out if you don't have Tcl/Tk on your system 2 | 3 | #GUIMODE=-DHAS_GUI 4 | 5 | # Modify the following line so that gcc can find the libtcl.so and 6 | # libtk.so libraries on your system. You may need to use the -L option 7 | # to tell gcc which directory to look in. Comment this out if you 8 | # don't have Tcl/Tk. 9 | 10 | TKLIBS=-L/usr/lib -ltk -ltcl 11 | 12 | # Modify the following line so that gcc can find the tcl.h and tk.h 13 | # header files on your system. Comment this out if you don't have 14 | # Tcl/Tk. 15 | 16 | TKINC=-isystem /usr/include 17 | 18 | ################################################## 19 | # You shouldn't need to modify anything below here 20 | ################################################## 21 | 22 | # Use this rule (make all) to build the Y86 tools. The variables you've 23 | # assigned to GUIMODE, TKLIBS, and TKINC will override the values that 24 | # are currently assigned in seq/Makefile and pipe/Makefile. 25 | all: 26 | (cd misc; make all) 27 | (cd pipe; make all GUIMODE=$(GUIMODE) TKLIBS="$(TKLIBS)" TKINC="$(TKINC)") 28 | (cd seq; make all GUIMODE=$(GUIMODE) TKLIBS="$(TKLIBS)" TKINC="$(TKINC)") 29 | (cd y86-code; make all) 30 | 31 | clean: 32 | rm -f *~ core 33 | (cd misc; make clean) 34 | (cd pipe; make clean) 35 | (cd seq; make clean) 36 | (cd y86-code; make clean) 37 | (cd ptest; make clean) 38 | 39 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/misc/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | CFLAGS=-Wall -O2 3 | LCFLAGS=-O2 4 | LEX = flex 5 | YACC=bison 6 | LEXLIB = -lfl 7 | YAS=./yas 8 | 9 | all: yis yas hcl2c 10 | 11 | # These are implicit rules for making .yo files from .ys files. 12 | # E.g., make sum.yo 13 | .SUFFIXES: .ys .yo 14 | .ys.yo: 15 | $(YAS) $*.ys 16 | 17 | # These are the explicit rules for making yis yas and hcl2c and hcl2v 18 | yas-grammar.o: yas-grammar.c 19 | $(CC) $(LCFLAGS) -c yas-grammar.c 20 | 21 | yas-grammar.c: yas-grammar.lex 22 | $(LEX) yas-grammar.lex 23 | mv lex.yy.c yas-grammar.c 24 | 25 | isa.o: isa.c isa.h 26 | $(CC) $(CFLAGS) -c isa.c 27 | 28 | yas.o: yas.c yas.h isa.h 29 | $(CC) $(CFLAGS) -c yas.c 30 | 31 | yas: yas.o yas-grammar.o isa.o 32 | $(CC) $(CFLAGS) yas-grammar.o yas.o isa.o ${LEXLIB} -o yas 33 | 34 | yis.o: yis.c isa.h 35 | $(CC) $(CFLAGS) -c yis.c 36 | 37 | yis: yis.o isa.o 38 | $(CC) $(CFLAGS) yis.o isa.o -o yis 39 | 40 | hcl2c: hcl.tab.c lex.yy.c node.c outgen.c 41 | $(CC) $(LCFLAGS) node.c lex.yy.c hcl.tab.c outgen.c -o hcl2c 42 | 43 | hcl2v: hcl.tab.c lex.yy.c node.c outgen.c 44 | $(CC) $(LCFLAGS) -DVLOG node.c lex.yy.c hcl.tab.c outgen.c -o hcl2v 45 | 46 | hcl2u: hcl.tab.c lex.yy.c node.c outgen.c 47 | $(CC) $(LCFLAGS) -DUCLID node.c lex.yy.c hcl.tab.c outgen.c -o hcl2u 48 | 49 | lex.yy.c: hcl.lex 50 | $(LEX) hcl.lex 51 | 52 | hcl.tab.c: hcl.y 53 | $(YACC) -d hcl.y 54 | 55 | clean: 56 | rm -f *.o *.yo *.exe yis yas hcl2c mux4 *~ core.* 57 | rm -f hcl.tab.c hcl.tab.h lex.yy.c 58 | 59 | 60 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/misc/README: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Y86 Assembler, Instruction Simulator, and HCL translator 3 | * 4 | * Copyright (c) 2002, R. Bryant and D. O'Hallaron, All rights reserved. 5 | * May not be used, modified, or copied without permission. 6 | ***********************************************************************/ 7 | 8 | This directory contains all of the source files for the following: 9 | 10 | YAS Y86 assembler 11 | YIS Y86 instruction level simulator 12 | HCL2C HCL to C translator 13 | HCL2V HCL to Verilog translator 14 | 15 | ********************* 16 | 1. Building the tools 17 | ********************* 18 | 19 | unix> make clean 20 | unix> make 21 | 22 | ******** 23 | 2. Files 24 | ******** 25 | 26 | Makefile Builds yas, yis, hcl2c, hcl2v 27 | README This file 28 | 29 | * Versions of Makefile in the student's distribution 30 | * (Instructor distribution only) 31 | Makefile-sim 32 | 33 | * Example programs for Part A of the CS:APP Architecture Lab 34 | examples.c C versions of three Y86 functions 35 | ans-copy.ys Solution copy function (instructor distribution only) 36 | ans-sum.ys Solution sum function (instructor distribution only) 37 | ans-rsum.ys Solution rsum function (instructor distribution only) 38 | 39 | 40 | * Instruction simulator code shared by yas, yis, ssim, ssim+, and psim 41 | isa.c 42 | isa.h 43 | 44 | * Files used to build the yas assembler 45 | yas The YAS binary 46 | yas.c yas source file and header file 47 | yas.h 48 | yas-grammar.lex Y86 lexical scanner spec 49 | yas-grammar.c Lexical scanner generated from yas-grammar.lex 50 | 51 | * Files used to build the yis instruction simulator 52 | yis The YIS binary 53 | yis.c yis source file 54 | 55 | * Files used to build the hcl2c translator 56 | hcl2c The HCL2C binary 57 | node.c auxiliary routines and header file 58 | node.h 59 | hcl.lex HCL lexical scanner spec 60 | lex.yy.c HCL lexical scanner generated from hcl.lex 61 | hcl.y HCL grammar 62 | hcl.tab.c HCL parser generated from hcl.y 63 | hcl.tab.h Token definitions 64 | 65 | * Example HCL programs used during the writing of the CS:APP book 66 | * (Instructor distribution only) 67 | frag.{hcl,c} 68 | mux4.{hcl,c} 69 | reg-file.{hcl,c} 70 | test.hcl 71 | 72 | 73 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/misc/examples.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Architecture Lab: Part A 3 | * 4 | * High level specs for the functions that the students will rewrite 5 | * in Y86 assembly language 6 | */ 7 | 8 | /* $begin examples */ 9 | /* linked list element */ 10 | typedef struct ELE { 11 | int val; 12 | struct ELE *next; 13 | } *list_ptr; 14 | 15 | /* sum_list - Sum the elements of a linked list */ 16 | int sum_list(list_ptr ls) 17 | { 18 | int val = 0; 19 | while (ls) { 20 | val += ls->val; 21 | ls = ls->next; 22 | } 23 | return val; 24 | } 25 | 26 | /* rsum_list - Recursive version of sum_list */ 27 | int rsum_list(list_ptr ls) 28 | { 29 | if (!ls) 30 | return 0; 31 | else { 32 | int val = ls->val; 33 | int rest = rsum_list(ls->next); 34 | return val + rest; 35 | } 36 | } 37 | 38 | /* copy_block - Copy src to dest and return xor checksum of src */ 39 | int copy_block(int *src, int *dest, int len) 40 | { 41 | int result = 0; 42 | while (len > 0) { 43 | int val = *src++; 44 | *dest++ = val; 45 | result ^= val; 46 | len--; 47 | } 48 | return result; 49 | } 50 | /* $end examples */ 51 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/misc/hcl.lex: -------------------------------------------------------------------------------- 1 | %{ 2 | #include 3 | #include "node.h" 4 | #define YYSTYPE node_ptr 5 | #include "hcl.tab.h" 6 | 7 | 8 | extern YYSTYPE yylval; 9 | extern int lineno; 10 | %} 11 | %% 12 | [ \r\t\f] ; 13 | [\n] lineno++; 14 | "#".*\n lineno++ ; 15 | quote return(QUOTE); 16 | boolsig return(BOOLARG); 17 | bool return(BOOL); 18 | intsig return(INTARG); 19 | int return(INT); 20 | in return(IN); 21 | '[^']*' yylval = make_quote(yytext); return(QSTRING); 22 | [a-zA-Z][a-zA-Z0-9_]* yylval = make_var(yytext); return(VAR); 23 | [0-9][0-9]* yylval = make_num(yytext); return(NUM); 24 | -[0-9][0-9]* yylval = make_num(yytext); return(NUM); 25 | "=" return(ASSIGN); 26 | ";" return(SEMI); 27 | ":" return(COLON); 28 | "," return(COMMA); 29 | "(" return(LPAREN); 30 | ")" return(RPAREN); 31 | "{" return(LBRACE); 32 | "}" return(RBRACE); 33 | "[" return(LBRACK); 34 | "]" return(RBRACK); 35 | "&&" return(AND); 36 | "||" return(OR); 37 | "!=" yylval = make_var(yytext); return(COMP); 38 | "==" yylval = make_var(yytext); return(COMP); 39 | "<" yylval = make_var(yytext); return(COMP); 40 | "<=" yylval = make_var(yytext); return(COMP); 41 | ">" yylval = make_var(yytext); return(COMP); 42 | ">=" yylval = make_var(yytext); return(COMP); 43 | "!" return(NOT); 44 | %% 45 | 46 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/misc/hcl.y: -------------------------------------------------------------------------------- 1 | %{ 2 | #include 3 | #include 4 | #include 5 | #include "node.h" 6 | #define YYSTYPE node_ptr 7 | 8 | /* Current line number. Maintained by lex */ 9 | int lineno = 1; 10 | #define ERRLIM 5 11 | int errcnt = 0; 12 | 13 | 14 | 15 | FILE *outfile; 16 | 17 | int yyparse(void); 18 | int yylex(void); 19 | 20 | void yyerror(const char *str) 21 | { 22 | fprintf(stderr, "Error, near line %d: %s\n", lineno, str); 23 | if (++errcnt > ERRLIM) { 24 | fprintf(stderr, "Too many errors, aborting\n"); 25 | exit(1); 26 | } 27 | } 28 | 29 | static char errmsg[1024]; 30 | void yyserror(const char *str, char *other) 31 | { 32 | sprintf(errmsg, str, other); 33 | yyerror(errmsg); 34 | } 35 | 36 | int yywrap() 37 | { 38 | return 1; 39 | } 40 | 41 | int main(int argc, char **argv) 42 | { 43 | init_node(argc, argv); 44 | outfile = stdout; 45 | yyparse(); 46 | finish_node(0); 47 | return errcnt != 0; 48 | } 49 | 50 | %} 51 | 52 | %token QUOTE BOOLARG BOOL INTARG INT QSTRING 53 | VAR NUM ASSIGN SEMI COLON COMMA LPAREN RPAREN LBRACE 54 | RBRACE LBRACK RBRACK AND OR NOT COMP IN 55 | 56 | /* All operators are left associative. Listed from lowest to highest */ 57 | %left OR 58 | %left AND 59 | %left NOT 60 | %left COMP 61 | %left IN 62 | 63 | %% 64 | 65 | statements: /* empty */ 66 | | statements statement 67 | ; 68 | 69 | statement: 70 | QUOTE QSTRING { insert_code($2); } 71 | | BOOLARG VAR QSTRING { add_arg($2, $3, 1); } 72 | | INTARG VAR QSTRING { add_arg($2, $3, 0); } 73 | | BOOL VAR ASSIGN expr SEMI { gen_funct($2, $4, 1); } 74 | | INT VAR ASSIGN expr SEMI { gen_funct($2, $4, 0); } 75 | ; 76 | 77 | expr: 78 | VAR { $$=$1; } 79 | | NUM { $$=$1; } 80 | | LPAREN expr RPAREN { $$=$2; } 81 | | NOT expr { $$=make_not($2); } 82 | | expr AND expr { $$=make_and($1, $3); } 83 | | expr OR expr { $$=make_or($1, $3); } 84 | | expr COMP expr { $$=make_comp($2,$1,$3); } 85 | | expr IN LBRACE exprlist RBRACE { $$=make_ele($1, $4);} 86 | | LBRACK caselist RBRACK { $$=$2; } 87 | ; 88 | 89 | exprlist: 90 | expr { $$=$1; } 91 | | exprlist COMMA expr { $$=concat($1, $3); } 92 | 93 | caselist: 94 | /* Empty */ { $$=NULL; } 95 | | caselist expr COLON expr SEMI { $$=concat($1, make_case($2, $4));} 96 | 97 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/misc/mux4.hcl: -------------------------------------------------------------------------------- 1 | #/* $begin sim-mux4-raw-hcl */ 2 | ## Simple example of an HCL file. 3 | ## This file can be converted to C using hcl2c, and then compiled. 4 | 5 | ## In this example, we will generate the MUX4 circuit shown in 6 | ## Section SLASHrefLBRACKsect:arch:hclsetRBRACK. It consists of a control block that generates 7 | ## bit-level signals s1 and s0 from the input signal code, 8 | ## and then uses these signals to control a 4-way multiplexor 9 | ## with data inputs A, B, C, and D. 10 | 11 | ## This code is embedded in a C program that reads 12 | ## the values of code, A, B, C, and D from the command line 13 | ## and then prints the circuit output 14 | 15 | ## Information that is inserted verbatim into the C file 16 | quote '#include ' 17 | quote '#include ' 18 | quote 'int code_val, s0_val, s1_val;' 19 | quote 'char **data_names;' 20 | 21 | ## Declarations of signals used in the HCL description and 22 | ## the corresponding C expressions. 23 | boolsig s0 's0_val' 24 | boolsig s1 's1_val' 25 | intsig code 'code_val' 26 | intsig A 'atoi(data_names[0])' 27 | intsig B 'atoi(data_names[1])' 28 | intsig C 'atoi(data_names[2])' 29 | intsig D 'atoi(data_names[3])' 30 | 31 | ## HCL descriptions of the logic blocks 32 | quote '/* $begin sim-mux4-s1-c */' 33 | bool s1 = code in { 2, 3 }; 34 | quote '/* $end sim-mux4-s1-c */' 35 | 36 | bool s0 = code in { 1, 3 }; 37 | 38 | int Out4 = [ 39 | !s1 && !s0 : A; # 00 40 | !s1 : B; # 01 41 | !s0 : C; # 10 42 | 1 : D; # 11 43 | ]; 44 | 45 | ## More information inserted verbatim into the C code to 46 | ## compute the values and print the output 47 | quote '/* $begin sim-mux4-main-c */' 48 | quote 'int main(int argc, char *argv[]) {' 49 | quote ' data_names = argv+2;' 50 | quote ' code_val = atoi(argv[1]);' 51 | quote ' s1_val = gen_s1();' 52 | quote ' s0_val = gen_s0();' 53 | quote ' printf("Out = %d\n", gen_Out4());' 54 | quote ' return 0;' 55 | quote '}' 56 | quote '/* $end sim-mux4-main-c */' 57 | #/* $end sim-mux4-raw-hcl */ 58 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/misc/node.h: -------------------------------------------------------------------------------- 1 | #ifndef NODE_H 2 | typedef enum { N_QUOTE, N_VAR, N_NUM, N_AND, N_OR, N_NOT, N_COMP, N_ELE, N_CASE } node_type_t; 3 | 4 | typedef struct NODE { 5 | node_type_t type; 6 | int isbool; /* Is this node a Boolean expression? */ 7 | char *sval; 8 | struct NODE *arg1; 9 | struct NODE *arg2; 10 | int ref; /* For var, how many times has it been referenced? */ 11 | struct NODE *next; 12 | } node_rec, *node_ptr; 13 | 14 | void init_node(int argc, char **argv); 15 | void finish_node(int check_ref); 16 | 17 | node_ptr make_quote(char *qstring); 18 | node_ptr make_var(char *name); 19 | node_ptr make_num(char *name); 20 | void set_bool(node_ptr varnode); 21 | node_ptr make_not(node_ptr arg); 22 | node_ptr make_and(node_ptr arg1, node_ptr arg2); 23 | node_ptr make_or(node_ptr arg1, node_ptr arg2); 24 | node_ptr make_comp(node_ptr op, node_ptr arg1, node_ptr arg2); 25 | node_ptr make_ele(node_ptr arg1, node_ptr arg2); 26 | node_ptr make_case(node_ptr arg1, node_ptr arg2); 27 | 28 | node_ptr concat(node_ptr n1, node_ptr n2); 29 | 30 | void insert_code(node_ptr qstring); 31 | void add_arg(node_ptr var, node_ptr qstring, int isbool); 32 | void gen_funct(node_ptr var, node_ptr expr, int isbool); 33 | #define NODE_H 34 | #endif 35 | 36 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/misc/outgen.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "outgen.h" 7 | /* Output generator that ensures no line exceeds specified number of columns */ 8 | 9 | #define STRING_LENGTH 1024 10 | 11 | FILE *outfile = NULL; 12 | int max_column = 80; 13 | int first_indent = 4; 14 | int other_indents = 2; 15 | int cur_pos = 0; 16 | int indent = 0; 17 | 18 | 19 | /* Controlling parameters */ 20 | void outgen_init(FILE *arg_outfile, int arg_max_column, int arg_first_indent, int arg_other_indents) { 21 | outfile = arg_outfile; 22 | max_column = arg_max_column; 23 | first_indent = arg_first_indent; 24 | other_indents = arg_other_indents; 25 | cur_pos = 0; 26 | indent = first_indent; 27 | } 28 | 29 | static void print_token(char *string) { 30 | if (outfile == NULL) 31 | outfile = stdout; 32 | int len = strlen(string); 33 | int i; 34 | if (len+cur_pos > max_column) { 35 | fprintf(outfile, "\n"); 36 | for (i = 0; i < indent; i++) 37 | fprintf(outfile, " "); 38 | cur_pos = indent; 39 | } 40 | fprintf(outfile, string); 41 | cur_pos += len; 42 | } 43 | 44 | 45 | /* Terminate statement and reset indentations */ 46 | void outgen_terminate() { 47 | printf("\n"); 48 | cur_pos = 0; 49 | indent = first_indent; 50 | } 51 | 52 | /* Output generator printing */ 53 | void outgen_print(char *fmt, ...) { 54 | char buf[STRING_LENGTH]; 55 | va_list argp; 56 | va_start(argp, fmt); 57 | vsprintf(buf, fmt, argp); 58 | va_end(argp); 59 | print_token(buf); 60 | } 61 | 62 | /* Increase indentation level */ 63 | void outgen_upindent() { 64 | indent += other_indents; 65 | } 66 | /* Decrease indentation level */ 67 | void outgen_downindent() { 68 | indent -= other_indents; 69 | } 70 | 71 | 72 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/misc/outgen.h: -------------------------------------------------------------------------------- 1 | /* Output generator that ensures no line exceeds specified number of columns */ 2 | 3 | /* Controlling parameters */ 4 | void outgen_init(FILE *outfile, int max_column, int first_indent, int other_indents); 5 | 6 | /* Terminate statement and reset indentations */ 7 | void outgen_terminate(); 8 | 9 | /* Output generator printing */ 10 | void outgen_print(char *fmt, ...); 11 | 12 | /* Increase indentation level */ 13 | void outgen_upindent(); 14 | /* Decrease indentation level */ 15 | void outgen_downindent(); 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/misc/yas-grammar.lex: -------------------------------------------------------------------------------- 1 | /* Grammar for Y86 Assembler */ 2 | #include "yas.h" 3 | unsigned int atoh(const char *); 4 | 5 | Instr rrmovl|cmovle|cmovl|cmove|cmovne|cmovge|cmovg|rmmovl|mrmovl|irmovl|addl|subl|andl|xorl|jmp|jle|jl|je|jne|jge|jg|call|ret|pushl|popl|"."byte|"."word|"."long|"."pos|"."align|halt|nop|iaddl|leave 6 | Letter [a-zA-Z] 7 | Digit [0-9] 8 | Ident {Letter}({Letter}|{Digit}|_)* 9 | Hex [0-9a-fA-F] 10 | Blank [ \t] 11 | Newline [\n\r] 12 | Return [\r] 13 | Char [^\n\r] 14 | Reg %eax|%ecx|%edx|%ebx|%esi|%edi|%esp|%ebp 15 | 16 | %x ERR COM 17 | %% 18 | 19 | ^{Char}*{Return}*{Newline} { save_line(yytext); REJECT;} /* Snarf input line */ 20 | #{Char}*{Return}*{Newline} {finish_line(); lineno++;} 21 | "//"{Char}*{Return}*{Newline} {finish_line(); lineno++;} 22 | "/*"{Char}*{Return}*{Newline} {finish_line(); lineno++;} 23 | {Blank}*{Return}*{Newline} {finish_line(); lineno++;} 24 | 25 | 26 | {Blank}+ ; 27 | "$"+ ; 28 | {Instr} add_instr(yytext); 29 | {Reg} add_reg(yytext); 30 | [-]?{Digit}+ add_num(atoi(yytext)); 31 | "0"[xX]{Hex}+ add_num(atoh(yytext)); 32 | [():,] add_punct(*yytext); 33 | {Ident} add_ident(yytext); 34 | {Char} {; BEGIN ERR;} 35 | {Char}*{Newline} {fail("Invalid line"); lineno++; BEGIN 0;} 36 | %% 37 | 38 | unsigned int atoh(const char *s) 39 | { 40 | return(strtoul(s, NULL, 16)); 41 | } 42 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/misc/yas.h: -------------------------------------------------------------------------------- 1 | void save_line(char *); 2 | void finish_line(); 3 | void add_reg(char *); 4 | void add_ident(char *); 5 | void add_instr(char *); 6 | void add_punct(char); 7 | void add_num(int); 8 | void fail(char *msg); 9 | 10 | /* Current line number */ 11 | int lineno; 12 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/misc/yis.c: -------------------------------------------------------------------------------- 1 | /* Instruction set simulator for Y86 Architecture */ 2 | 3 | #include 4 | #include 5 | 6 | #include "isa.h" 7 | 8 | /* YIS never runs in GUI mode */ 9 | int gui_mode = 0; 10 | 11 | void usage(char *pname) 12 | { 13 | printf("Usage: %s code_file [max_steps]\n", pname); 14 | exit(0); 15 | } 16 | 17 | int main(int argc, char *argv[]) 18 | { 19 | FILE *code_file; 20 | int max_steps = 10000; 21 | 22 | state_ptr s = new_state(MEM_SIZE); 23 | mem_t saver = copy_reg(s->r); 24 | mem_t savem; 25 | int step = 0; 26 | 27 | stat_t e = STAT_AOK; 28 | 29 | if (argc < 2 || argc > 3) 30 | usage(argv[0]); 31 | code_file = fopen(argv[1], "r"); 32 | if (!code_file) { 33 | fprintf(stderr, "Can't open code file '%s'\n", argv[1]); 34 | exit(1); 35 | } 36 | 37 | if (!load_mem(s->m, code_file, 1)) { 38 | printf("Exiting\n"); 39 | return 1; 40 | } 41 | 42 | savem = copy_mem(s->m); 43 | 44 | if (argc > 2) 45 | max_steps = atoi(argv[2]); 46 | 47 | for (step = 0; step < max_steps && e == STAT_AOK; step++) 48 | e = step_state(s, stdout); 49 | 50 | printf("Stopped in %d steps at PC = 0x%x. Status '%s', CC %s\n", 51 | step, s->pc, stat_name(e), cc_name(s->cc)); 52 | 53 | printf("Changes to registers:\n"); 54 | diff_reg(saver, s->r, stdout); 55 | 56 | printf("\nChanges to memory:\n"); 57 | diff_mem(savem, s->m, stdout); 58 | 59 | free_state(s); 60 | free_reg(saver); 61 | free_mem(savem); 62 | 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/pipe/Makefile: -------------------------------------------------------------------------------- 1 | # Modify this line to indicate the default version to build 2 | 3 | VERSION=std 4 | 5 | # Comment this out if you don't have Tcl/Tk on your system 6 | 7 | GUIMODE=-DHAS_GUI 8 | 9 | # Modify the following line so that gcc can find the libtcl.so and 10 | # libtk.so libraries on your system. You may need to use the -L option 11 | # to tell gcc which directory to look in. Comment this out if you 12 | # don't have Tcl/Tk. 13 | 14 | TKLIBS=-L/usr/lib -ltk -ltcl 15 | 16 | # Modify the following line so that gcc can find the tcl.h and tk.h 17 | # header files on your system. Comment this out if you don't have 18 | # Tcl/Tk. 19 | 20 | TKINC=-isystem /usr/include 21 | 22 | # Modify these two lines to choose your compiler and compile time 23 | # flags. 24 | 25 | CC=gcc 26 | CFLAGS=-Wall -O2 27 | 28 | ################################################## 29 | # You shouldn't need to modify anything below here 30 | ################################################## 31 | 32 | MISCDIR=../misc 33 | HCL2C=$(MISCDIR)/hcl2c 34 | INC=$(TKINC) -I$(MISCDIR) $(GUIMODE) 35 | LIBS=$(TKLIBS) -lm 36 | YAS = ../misc/yas 37 | 38 | all: psim drivers 39 | 40 | # This rule builds the PIPE simulator 41 | psim: psim.c sim.h pipe-$(VERSION).hcl $(MISCDIR)/isa.c $(MISCDIR)/isa.h 42 | # Building the pipe-$(VERSION).hcl version of PIPE 43 | $(HCL2C) -n pipe-$(VERSION).hcl < pipe-$(VERSION).hcl > pipe-$(VERSION).c 44 | $(CC) $(CFLAGS) $(INC) -o psim psim.c pipe-$(VERSION).c \ 45 | $(MISCDIR)/isa.c $(LIBS) 46 | 47 | # This rule builds driver programs for Part C of the Architecture Lab 48 | drivers: 49 | ./gen-driver.pl -n 4 -f ncopy.ys > sdriver.ys 50 | ../misc/yas sdriver.ys 51 | ./gen-driver.pl -n 63 -f ncopy.ys > ldriver.ys 52 | ../misc/yas ldriver.ys 53 | 54 | # These are implicit rules for assembling .yo files from .ys files. 55 | .SUFFIXES: .ys .yo 56 | .ys.yo: 57 | $(YAS) $*.ys 58 | 59 | 60 | clean: 61 | rm -f psim pipe-*.c *.o *.exe *~ sdriver.* ldriver.* 62 | 63 | 64 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/pipe/benchmark.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | #!/usr/local/bin/perl 3 | 4 | # 5 | # benchmark.pl - Run test of pipeline on ncopy for different block sizes 6 | # and determine CPE (cycles per element) 7 | # 8 | use Getopt::Std; 9 | 10 | # 11 | # Configuration 12 | # 13 | $blocklen = 64; 14 | $yas = "../misc/yas"; 15 | $pipe = "./psim"; 16 | $gendriver = "./gen-driver.pl"; 17 | $fname = "bdriver"; 18 | $verbose = 1; 19 | 20 | ## Grading criteria 21 | $totalpoints = 60; 22 | # What CPE is required to get full credit? 23 | $fullcpe = 10.0; 24 | # What CPE is required to get nonzero credit: 25 | $threshcpe = 12.5; 26 | 27 | 28 | 29 | # 30 | # usage - Print the help message and terminate 31 | # 32 | sub usage { 33 | print STDERR "Usage: $0 [-hq] [-n N] -f FILE\n"; 34 | print STDERR " -h Print help message\n"; 35 | print STDERR " -q Quiet mode (default verbose)\n"; 36 | print STDERR " -n N Set max number of elements up to 64 (default $blocklen)\n"; 37 | print STDERR " -f FILE Input .ys file is FILE\n"; 38 | die "\n"; 39 | } 40 | 41 | getopts('hqn:f:'); 42 | 43 | if ($opt_h) { 44 | usage(); 45 | } 46 | 47 | if ($opt_q) { 48 | $verbose = 0; 49 | } 50 | 51 | if ($opt_n) { 52 | $blocklen = $opt_n; 53 | if ($blocklen < 0 || $blocklen > 64) { 54 | print STDERR "n must be between 0 and 64\n"; 55 | die "\n"; 56 | } 57 | } 58 | 59 | # Filename is required 60 | if (!$opt_f) { 61 | $ncopy = "ncopy"; 62 | } else { 63 | $ncopy = $opt_f; 64 | # Strip off .ys 65 | $ncopy =~ s/\.ys//; 66 | } 67 | 68 | if ($verbose) { 69 | print "\t$ncopy\n"; 70 | } 71 | 72 | $tcpe = 0; 73 | for ($i = 0; $i <= $blocklen; $i++) { 74 | !(system "$gendriver -n $i -f $ncopy.ys > $fname$i.ys") || 75 | die "Couldn't generate driver file $fname$i.ys\n"; 76 | !(system "$yas $fname$i.ys") || 77 | die "Couldn't assemble file $fname$i.ys\n"; 78 | $stat = `$pipe -v 0 $fname$i.yo` || 79 | die "Couldn't simulate file $fname$i.yo\n"; 80 | # print $stat; 81 | !(system "rm $fname$i.ys $fname$i.yo") || 82 | die "Couldn't remove files $fname$i.ys and/or $fname$i.yo\n"; 83 | chomp $stat; 84 | $stat =~ s/[ ]*CPI:[ ]*//; 85 | $stat =~ s/ cycles.*//; 86 | if ($i > 0) { 87 | $cpe = $stat/$i; 88 | if ($verbose) { 89 | printf "%d\t%d\t%.2f\n", $i, $stat, $cpe; 90 | } 91 | $tcpe += $cpe; 92 | } else { 93 | if ($verbose) { 94 | printf "%d\t%d\n", $i, $stat; 95 | } 96 | } 97 | 98 | } 99 | 100 | $acpe = $tcpe/$blocklen; 101 | printf "Average CPE\t%.2f\n", $acpe; 102 | 103 | ## Compute Score 104 | $score = 0; 105 | if ($acpe <= $fullcpe) { 106 | $score = $totalpoints; 107 | } elsif ($acpe <= $threshcpe) { 108 | $score = $totalpoints * ($threshcpe - $acpe)/($threshcpe - $fullcpe); 109 | } 110 | printf "Score\t%.1f/%.1f\n", $score, $totalpoints; 111 | 112 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/pipe/check-len.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | # Check length of ncopy function in .yo file 4 | # Assumes that function starts with label "ncopy:" 5 | # and finishes with label "End:" 6 | 7 | $startpos = -1; 8 | $endpos = -1; 9 | 10 | while (<>) { 11 | $line = $_; 12 | if ($line =~ /(0x[0-9a-fA-F]+):.* ncopy:/) { 13 | $startpos = hex($1); 14 | } 15 | if ($line =~ /(0x[0-9a-fA-F]+):.* End:/) { 16 | $endpos = hex($1); 17 | } 18 | } 19 | 20 | if ($startpos >= 0 && $endpos > $startpos) { 21 | $len = $endpos - $startpos; 22 | print "ncopy length = $len bytes\n"; 23 | } else { 24 | print "Couldn't determine ncopy length\n"; 25 | } 26 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/pipe/ncopy.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int src[8], dst[8]; 4 | 5 | /* $begin ncopy */ 6 | /* 7 | * ncopy - copy src to dst, returning number of positive ints 8 | * contained in src array. 9 | */ 10 | int ncopy(int *src, int *dst, int len) 11 | { 12 | int count = 0; 13 | int val; 14 | 15 | while (len > 0) { 16 | val = *src++; 17 | *dst++ = val; 18 | if (val > 0) 19 | count++; 20 | len--; 21 | } 22 | return count; 23 | } 24 | /* $end ncopy */ 25 | 26 | int main() 27 | { 28 | int i, count; 29 | 30 | for (i=0; i<8; i++) 31 | src[i]= i+1; 32 | count = ncopy(src, dst, 8); 33 | printf ("count=%d\n", count); 34 | exit(0); 35 | } 36 | 37 | 38 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/pipe/ncopy.ys: -------------------------------------------------------------------------------- 1 | #/* $begin ncopy-ys */ 2 | ################################################################## 3 | # ncopy.ys - Copy a src block of len ints to dst. 4 | # Return the number of positive ints (>0) contained in src. 5 | # 6 | # Include your name and ID here. 7 | # 8 | # Describe how and why you modified the baseline code. 9 | # 10 | ################################################################## 11 | # Do not modify this portion 12 | # Function prologue. 13 | ncopy: pushl %ebp # Save old frame pointer 14 | rrmovl %esp,%ebp # Set up new frame pointer 15 | pushl %esi # Save callee-save regs 16 | pushl %ebx 17 | pushl %edi 18 | mrmovl 8(%ebp),%ebx # src 19 | mrmovl 16(%ebp),%edx # len 20 | mrmovl 12(%ebp),%ecx # dst 21 | 22 | ################################################################## 23 | # You can modify this portion 24 | # Loop header 25 | xorl %eax,%eax # count = 0; 26 | andl %edx,%edx # len <= 0? 27 | jle Done # if so, goto Done: 28 | 29 | Loop: mrmovl (%ebx), %esi # read val from src... 30 | rmmovl %esi, (%ecx) # ...and store it to dst 31 | andl %esi, %esi # val <= 0? 32 | jle Npos # if so, goto Npos: 33 | irmovl $1, %edi 34 | addl %edi, %eax # count++ 35 | Npos: irmovl $1, %edi 36 | subl %edi, %edx # len-- 37 | irmovl $4, %edi 38 | addl %edi, %ebx # src++ 39 | addl %edi, %ecx # dst++ 40 | andl %edx,%edx # len > 0? 41 | jg Loop # if so, goto Loop: 42 | ################################################################## 43 | # Do not modify the following section of code 44 | # Function epilogue. 45 | Done: 46 | popl %edi # Restore callee-save registers 47 | popl %ebx 48 | popl %esi 49 | rrmovl %ebp, %esp 50 | popl %ebp 51 | ret 52 | ################################################################## 53 | # Keep the following label at the end of your function 54 | End: 55 | #/* $end ncopy-ys */ 56 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/pipe/pipeline.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * pipe.h 3 | * 4 | * Code for implementing pipelined processor simulators 5 | ******************************************************************************/ 6 | 7 | #ifndef PIPE_H 8 | #define PIPE_H 9 | 10 | /****************************************************************************** 11 | * #includes 12 | ******************************************************************************/ 13 | 14 | #include 15 | 16 | /****************************************************************************** 17 | * typedefs 18 | ******************************************************************************/ 19 | 20 | /* Different control operations for pipeline register */ 21 | /* LOAD: Copy next state to current */ 22 | /* STALL: Keep current state unchanged */ 23 | /* BUBBLE: Set current state to nop */ 24 | /* ERROR: Occurs when both stall & load signals set */ 25 | 26 | typedef enum { P_LOAD, P_STALL, P_BUBBLE, P_ERROR } p_stat_t; 27 | 28 | typedef struct { 29 | /* Current and next register state */ 30 | void *current; 31 | void *next; 32 | /* Contents of register when bubble occurs */ 33 | void *bubble_val; 34 | /* Number of state bytes */ 35 | int count; 36 | /* How should state be updated next time? */ 37 | p_stat_t op; 38 | } pipe_ele, *pipe_ptr; 39 | 40 | /****************************************************************************** 41 | * function declarations 42 | ******************************************************************************/ 43 | 44 | /* Create new pipe with count bytes of state */ 45 | /* bubble_val indicates state corresponding to pipeline bubble */ 46 | pipe_ptr new_pipe(int count, void *bubble_val); 47 | 48 | /* Update all pipes */ 49 | void update_pipes(); 50 | 51 | /* Set all pipes to bubble values */ 52 | void clear_pipes(); 53 | 54 | /* Utility code */ 55 | 56 | /* Print hex/oct/binary format with leading zeros */ 57 | /* bpd denotes bits per digit Should be in range 1-4, 58 | bpw denotes bits per word.*/ 59 | void wprint(unsigned x, int bpd, int bpw, FILE *fp); 60 | void wstring(unsigned x, int bpd, int bpw, char *s); 61 | 62 | /******************************************************************************/ 63 | 64 | #endif /* PIPE_H */ 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/pipe/stages.h: -------------------------------------------------------------------------------- 1 | /* 2 | * stages.h - Defines the layout of the pipe registers 3 | * Declares the functions that implement the pipeline stages 4 | */ 5 | 6 | 7 | /********** Pipeline register contents **************/ 8 | 9 | /* Program Counter */ 10 | typedef struct { 11 | word_t pc; 12 | stat_t status; 13 | } pc_ele, *pc_ptr; 14 | 15 | /* IF/ID Pipe Register */ 16 | typedef struct { 17 | byte_t icode; /* Single byte instruction code */ 18 | byte_t ifun; /* ALU/JMP qualifier */ 19 | byte_t ra; /* Register ra ID */ 20 | byte_t rb; /* Register rb ID */ 21 | word_t valc; /* Instruction word encoding immediate data */ 22 | word_t valp; /* Incremented program counter */ 23 | stat_t status; 24 | /* The following is included for debugging */ 25 | word_t stage_pc; 26 | } if_id_ele, *if_id_ptr; 27 | 28 | /* ID/EX Pipe Register */ 29 | typedef struct { 30 | byte_t icode; /* Instruction code */ 31 | byte_t ifun; /* ALU/JMP qualifier */ 32 | word_t valc; /* Immediate data */ 33 | word_t vala; /* valA */ 34 | word_t valb; /* valB */ 35 | byte_t srca; /* Source Reg ID for valA */ 36 | byte_t srcb; /* Source Reg ID for valB */ 37 | byte_t deste; /* Destination register for valE */ 38 | byte_t destm; /* Destination register for valM */ 39 | stat_t status; 40 | /* The following is included for debugging */ 41 | word_t stage_pc; 42 | } id_ex_ele, *id_ex_ptr; 43 | 44 | /* EX/MEM Pipe Register */ 45 | typedef struct { 46 | byte_t icode; /* Instruction code */ 47 | byte_t ifun; /* ALU/JMP qualifier */ 48 | bool_t takebranch; /* Taken branch signal */ 49 | word_t vale; /* valE */ 50 | word_t vala; /* valA */ 51 | byte_t deste; /* Destination register for valE */ 52 | byte_t destm; /* Destination register for valM */ 53 | byte_t srca; /* Source register for valA */ 54 | stat_t status; 55 | /* The following is included for debugging */ 56 | word_t stage_pc; 57 | } ex_mem_ele, *ex_mem_ptr; 58 | 59 | /* Mem/WB Pipe Register */ 60 | typedef struct { 61 | byte_t icode; /* Instruction code */ 62 | byte_t ifun; /* ALU/JMP qualifier */ 63 | word_t vale; /* valE */ 64 | word_t valm; /* valM */ 65 | byte_t deste; /* Destination register for valE */ 66 | byte_t destm; /* Destination register for valM */ 67 | stat_t status; 68 | /* The following is included for debugging */ 69 | word_t stage_pc; 70 | } mem_wb_ele, *mem_wb_ptr; 71 | 72 | /************ Global Declarations ********************/ 73 | 74 | extern pc_ele bubble_pc; 75 | extern if_id_ele bubble_if_id; 76 | extern id_ex_ele bubble_id_ex; 77 | extern ex_mem_ele bubble_ex_mem; 78 | extern mem_wb_ele bubble_mem_wb; 79 | 80 | /************ Function declarations *******************/ 81 | 82 | /* Stage functions */ 83 | void do_if_stage(); 84 | void do_id_wb_stages(); /* Both ID and WB */ 85 | void do_ex_stage(); 86 | void do_mem_stage(); 87 | 88 | /* Set stalling conditions for different stages */ 89 | void do_stall_check(); 90 | 91 | 92 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/ptest/Makefile: -------------------------------------------------------------------------------- 1 | SIM=../pipe/psim 2 | TFLAGS= 3 | 4 | ISADIR = ../misc 5 | YAS=$(ISADIR)/yas 6 | 7 | .SUFFIXES: .ys .yo 8 | 9 | .ys.yo: 10 | $(YAS) $*.ys 11 | 12 | test: 13 | ./optest.pl -s $(SIM) $(TFLAGS) 14 | ./jtest.pl -s $(SIM) $(TFLAGS) 15 | ./ctest.pl -s $(SIM) $(TFLAGS) 16 | ./htest.pl -s $(SIM) $(TFLAGS) 17 | 18 | clean: 19 | rm -f *.o *~ *.yo *.ys 20 | 21 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/ptest/README: -------------------------------------------------------------------------------- 1 | This directory contains Perl scripts that provide comprehensive 2 | regression testing of the different Y86 simulators. There are four 3 | basic test types, implemented as four different scripts: 4 | 5 | optest.pl: Tests each individual instruction type 6 | jtest.pl: Tests all of the jump types under different conditions 7 | ctest.pl: Tests different pipeline control combinations 8 | htest.pl: Tests many different hazard possibilities 9 | This involves running 864+ tests, so it takes a while. 10 | 11 | Each of the tests has the following optional arguments: 12 | -s simfile Use simfile as simulator (default ../pipe/psim). 13 | -i Test the iaddl instruction 14 | -l Test the leave instruction 15 | 16 | You can use make to run all four test programs. Options to make include: 17 | 18 | SIM=simfile 19 | TFLAGS= 20 | 21 | For example, you could say: 22 | make SIM=../pipe/psim TFLAGS=-il 23 | to test the pipeline simulator including both the iaddl and leave instructions. 24 | 25 | When the test program detects an erroneous simulation, it leaves the 26 | .ys file in the directory (ordinarily it deletes the test code it 27 | generates). You can then run a simulator (the GUI version is 28 | especially helpful here) on one of these failing cases. Suppose the 29 | failing test is in file bad-test.ys. Then you can execute "make 30 | bad-test.yo" to create the object code, and simulate it with one of 31 | the simulators. 32 | 33 | Note that the standard test code only detects functional bugs, where the 34 | processor simulation produces different results than would be 35 | predicted by simulating at the ISA level. 36 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/ptest/ctest.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | #!/usr/local/bin/perl 3 | # Test for pipeline hazard combinations 4 | 5 | use Getopt::Std; 6 | use lib "."; 7 | use tester; 8 | 9 | cmdline(); 10 | 11 | # Instruction templates 12 | $tcount = 8; 13 | 14 | @templates = 15 | ( 16 | "||jne target\n\thalt\ntarget:|", # M 17 | "|||ret", # R 18 | 19 | "||mrmovl (%eax),%esp|ret", # G1a 20 | "|mrmovl (%eax),%esp||ret", # G1b 21 | "mrmovl (%eax),%esp|||ret", # G1c 22 | "||irmovl \$3,%eax|rrmovl %eax,%edx", # G2a 23 | "|irmovl \$3,%eax||rrmovl %eax,%edx", # G2b 24 | "irmovl \$3,%eax|||rrmovl %eax,%edx", # G2c 25 | ); 26 | 27 | # Try combining two templates to generate test sequence 28 | sub make_test 29 | { 30 | local ($t1, $t2) = @_; 31 | $ok = 1; 32 | @test1 = split(/\|/, $t1); 33 | @test2 = split(/\|/, $t2); 34 | for ($i = 0; $i < 4; $i++) { 35 | if ($test1[$i] eq "") { 36 | if ($test2[$i] eq "") { 37 | $test[$i] = "nop"; 38 | } else { 39 | $test[$i] = $test2[$i]; 40 | } 41 | } else { 42 | if ($test2[$i] eq "") { 43 | $test[$i] = $test1[$i]; 44 | } else { 45 | if ($test1[$i] eq $test2[$i]) { 46 | # $ok = 0; 47 | $test[$i] = $test1[$i]; 48 | } else { 49 | $ok = 0; 50 | $test[$i] = "XXX"; 51 | } 52 | } 53 | } 54 | } 55 | if ($ok) { 56 | &gen_test($test[0], $test[1], $test[2], $test[3]); 57 | } 58 | 59 | } 60 | 61 | $testcnt = 0; 62 | 63 | # Generate test with 4 instructions inserted 64 | sub gen_test 65 | { 66 | local ($i1, $i2, $i3, $i4) = @_; 67 | $tname = "c-$testcnt"; 68 | $testcnt++; 69 | open(YFILE, ">$tname.ys") || die "Can't write to $tname.ys\n"; 70 | 71 | print YFILE <$tname.ys") || die "Can't write to $tname.ys\n"; 59 | &gen_test($e, "nop", $s); 60 | close YFILE; 61 | &run_test($tname); 62 | 63 | # Two instructions in succession 64 | $tname = "e-$ei-$si"; 65 | open (YFILE, ">$tname.ys") || die "Can't write to $tname.ys\n"; 66 | &gen_test($e, "", $s); 67 | close YFILE; 68 | &run_test($tname); 69 | $si++; 70 | } 71 | $si = 0; 72 | $ei++; 73 | } 74 | 75 | &test_stat(); 76 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/ptest/jtest.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | #!/usr/local/bin/perl 3 | # Test jump instructions 4 | 5 | use Getopt::Std; 6 | use lib "."; 7 | use tester; 8 | 9 | cmdline(); 10 | 11 | @vals = (32, 64); 12 | 13 | @instr = ("jmp", "jle", "jl", "je", "jne", "jge", "jg", "call"); 14 | 15 | # Create set of forward tests 16 | foreach $t (@instr) { 17 | foreach $va (@vals) { 18 | foreach $vb (@vals) { 19 | $tname = "jf-$t-$va-$vb"; 20 | open (YFILE, ">$tname.ys") || die "Can't write to $tname.ys\n"; 21 | print YFILE <$tname.ys") || die "Can't write to $tname.ys\n"; 56 | print YFILE <$tname.ys") || die "Can't write to $tname.ys\n"; 96 | print YFILE <$tname.ys") || die "Can't write to $tname.ys\n"; 21 | print YFILE <$tname.ys") || die "Can't write to $tname.ys\n"; 43 | print YFILE <$tname.ys") || die "Can't write to $tname.ys\n"; 66 | print YFILE <$tname.ys") || die "Can't write to $tname.ys\n"; 95 | print YFILE <seq-$(VERSION).c 44 | $(CC) $(CFLAGS) $(INC) -o ssim \ 45 | seq-$(VERSION).c ssim.c $(MISCDIR)/isa.c $(LIBS) 46 | 47 | # This rule builds the SEQ+ simulator (ssim+) 48 | ssim+: seq+-std.hcl ssim.c sim.h $(MISCDIR)/isa.c $(MISCDIR)/isa.h 49 | # Building the seq+-std.hcl version of SEQ+ 50 | $(HCL2C) -n seq+-std.hcl seq+-std.c 51 | $(CC) $(CFLAGS) $(INC) -o ssim+ \ 52 | seq+-std.c ssim.c $(MISCDIR)/isa.c $(LIBS) 53 | 54 | # These are implicit rules for assembling .yo files from .ys files. 55 | .SUFFIXES: .ys .yo 56 | .ys.yo: 57 | $(YAS) $*.ys 58 | 59 | 60 | clean: 61 | rm -f ssim ssim+ seq*-*.c *.o *~ *.exe *.yo *.ys 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/seq/sim.h: -------------------------------------------------------------------------------- 1 | /********** Defines **************/ 2 | 3 | /* Get ra out of one byte regid field */ 4 | #define GET_RA(r) HI4(r) 5 | 6 | /* Get rb out of one byte regid field */ 7 | #define GET_RB(r) LO4(r) 8 | 9 | 10 | /************ Global state declaration ****************/ 11 | 12 | /* Determines whether running SEQ or SEQ+ */ 13 | extern int plusmode; 14 | 15 | /* Both instruction and data memory */ 16 | extern mem_t mem; 17 | 18 | /* Keep track of range of addresses that have been written */ 19 | extern int minAddr; 20 | extern int memCnt; 21 | 22 | /* Register file */ 23 | extern mem_t reg; 24 | /* Condition code register */ 25 | extern cc_t cc; 26 | /* Program counter */ 27 | extern word_t pc; 28 | 29 | /* For seq+ */ 30 | /* Results computed by previous instruction. 31 | Used to compute PC in current instruction */ 32 | extern byte_t prev_icode; 33 | extern byte_t prev_ifun; 34 | extern word_t prev_valc; 35 | extern word_t prev_valm; 36 | extern word_t prev_valp; 37 | extern bool_t prev_bcond; 38 | 39 | /* Intermdiate stage values that must be used by control functions */ 40 | extern byte_t imem_icode; 41 | extern byte_t imem_ifun; 42 | extern byte_t icode; 43 | extern word_t ifun; 44 | extern word_t ra; 45 | extern word_t rb; 46 | extern word_t valc; 47 | extern word_t valp; 48 | extern bool_t imem_error; 49 | extern bool_t instr_valid; 50 | extern word_t vala; 51 | extern word_t valb; 52 | extern word_t vale; 53 | extern bool_t bcond; 54 | extern bool_t cond; 55 | extern word_t valm; 56 | extern bool_t dmem_error; 57 | extern byte_t status; 58 | 59 | /* Log file */ 60 | extern FILE *dumpfile; 61 | 62 | 63 | /* Sets the simulator name (called from main routine in HCL file) */ 64 | void set_simname(char *name); 65 | 66 | /* Initialize simulator */ 67 | void sim_init(); 68 | 69 | /* Reset simulator state, including register, instruction, and data memories */ 70 | void sim_reset(); 71 | 72 | /* 73 | Run processor until one of following occurs: 74 | - An status error is encountered 75 | - max_instr instructions have completed 76 | 77 | Return number of instructions executed. 78 | if statusp nonnull, then will be set to status of final instruction 79 | if ccp nonnull, then will be set to condition codes of final instruction 80 | */ 81 | int sim_run(int max_instr, byte_t *statusp, cc_t *ccp); 82 | 83 | /* If dumpfile set nonNULL, lots of status info printed out */ 84 | void sim_set_dumpfile(FILE *file); 85 | 86 | /* 87 | * sim_log dumps a formatted string to the dumpfile, if it exists 88 | * accepts variable argument list 89 | */ 90 | void sim_log( const char *format, ... ); 91 | 92 | 93 | /******************* GUI Interface Functions **********************/ 94 | #ifdef HAS_GUI 95 | 96 | void signal_register_clear(); 97 | 98 | void report_pc(unsigned pc); 99 | 100 | void report_state(char *id, char *txt); 101 | 102 | void show_cc(cc_t cc); 103 | 104 | void create_memory_display(); 105 | void set_memory(int addr, int val); 106 | #endif 107 | 108 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/y86-code/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | CFLAGS=-Wall -O2 3 | 4 | ISADIR = ../misc 5 | YAS=$(ISADIR)/yas 6 | YIS=$(ISADIR)/yis 7 | PIPE=../pipe/psim 8 | SEQ=../seq/ssim 9 | SEQ+ =../seq/ssim+ 10 | 11 | YOFILES = abs-asum-cmov.yo abs-asum-jmp.yo asum.yo asumr.yo asumi.yo asuml.yo cjr.yo j-cc.yo poptest.yo pushquestion.yo pushtest.yo prog1.yo prog2.yo prog3.yo prog4.yo prog5.yo prog6.yo prog7.yo prog8.yo prog9.yo prog10.yo ret-hazard.yo 12 | 13 | PIPEFILES = asum.pipe asumr.pipe cjr.pipe j-cc.pipe poptest.pipe pushquestion.pipe pushtest.pipe prog1.pipe prog2.pipe prog3.pipe prog4.pipe prog5.pipe prog6.pipe prog7.pipe prog8.pipe ret-hazard.pipe 14 | 15 | SEQFILES = asum.seq asumr.seq cjr.seq j-cc.seq poptest.seq pushquestion.seq pushtest.seq prog1.seq prog2.seq prog3.seq prog4.seq prog5.seq prog6.seq prog7.seq prog8.seq ret-hazard.seq 16 | 17 | SEQ+FILES = asum.seq+ asumr.seq+ cjr.seq+ j-cc.seq+ poptest.seq+ pushquestion.seq+ pushtest.seq+ prog1.seq+ prog2.seq+ prog3.seq+ prog4.seq+ prog5.seq+ prog6.seq+ prog7.seq+ prog8.seq+ ret-hazard.seq+ 18 | 19 | .SUFFIXES: 20 | .SUFFIXES: .c .s .o .ys .yo .yis .pipe .seq .seq+ 21 | 22 | all: $(YOFILES) 23 | 24 | test: testpsim testssim testssim+ 25 | 26 | testpsim: $(PIPEFILES) 27 | grep "ISA Check" *.pipe 28 | rm $(PIPEFILES) 29 | 30 | testssim: $(SEQFILES) 31 | grep "ISA Check" *.seq 32 | rm $(SEQFILES) 33 | 34 | testssim+: $(SEQ+FILES) 35 | grep "ISA Check" *.seq+ 36 | rm $(SEQ+FILES) 37 | 38 | .ys.yo: 39 | $(YAS) $*.ys 40 | 41 | .yo.yis: $(YIS) 42 | $(YIS) $*.yo > $*.yis 43 | 44 | .yo.pipe: $(PIPE) 45 | $(PIPE) -t $*.yo > $*.pipe 46 | 47 | .yo.seq: $(SEQ) 48 | $(SEQ) -t $*.yo > $*.seq 49 | 50 | .yo.seq+: $(SEQ+) 51 | $(SEQ+) -t $*.yo > $*.seq+ 52 | 53 | clean: 54 | rm -f *.o *.yis *~ *.yo *.pipe *.seq *.seq+ core 55 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/y86-code/README: -------------------------------------------------------------------------------- 1 | This directory contains examples of Y86 assembly code programs 2 | (extension `.ys') used in Chapter 4 of CS:APP2e. 3 | 4 | Given an assembly code file "file.ys", you can assemble it with the 5 | command "make file.yo". The resulting file is in the "object code" 6 | format described in the book. 7 | 8 | You can assemble and simulate all the test programs in this directory 9 | as follows: 10 | 11 | PIPE: make testpsim 12 | SEQ: make testssim 13 | SEQ+: make testssim+ 14 | 15 | Each of these commands will cause a number of programs to be assembled 16 | and simulated. Lots of things will scroll by, but you should see the message 17 | "ISA Check Succeeds" for each of the programs tested. 18 | 19 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/y86-code/abs-asum-cmov.ys: -------------------------------------------------------------------------------- 1 | # Modification of asum code to compute absolute values of entries. 2 | # This version uses a conditional jump 3 | # Execution begins at address 0 4 | .pos 0 5 | init: irmovl Stack, %esp # Set up Stack pointer 6 | irmovl Stack, %ebp # Set up base pointer 7 | jmp Main # Execute main program 8 | 9 | # Array of 4 elements 10 | .align 4 11 | array: .long 0x0000000d 12 | .long 0xffffff40 # -0xc0 13 | .long 0x00000b00 14 | .long 0xffff6000 # -0xa0000 15 | 16 | Main: irmovl $4,%eax 17 | pushl %eax # Push 4 18 | irmovl array,%edx 19 | pushl %edx # Push array 20 | call AbsSum # Sum(array, 4) 21 | halt 22 | 23 | # int AbsSum(int *Start, int Count) 24 | AbsSum: 25 | pushl %ebp 26 | rrmovl %esp,%ebp 27 | mrmovl 8(%ebp),%ecx # ecx = Start 28 | mrmovl 12(%ebp),%edx # edx = Count 29 | irmovl $0, %eax # sum = 0 30 | andl %edx,%edx 31 | je End 32 | /* $begin abs-sum-cmov-ys 0 */ 33 | Loop: 34 | mrmovl (%ecx),%esi # get x = *Start 35 | irmovl $0,%edi # 0 36 | subl %esi,%edi # -x 37 | cmovg %edi,%esi # if -x > 0 then x = -x 38 | addl %esi,%eax # add x to sum 39 | irmovl $4,%ebx # 40 | addl %ebx,%ecx # Start++ 41 | irmovl $-1,%ebx # 42 | addl %ebx,%edx # Count-- 43 | jne Loop # Stop when 0 44 | /* $end abs-sum-cmov-ys 0 */ 45 | End: 46 | popl %ebp 47 | ret 48 | 49 | .pos 0x100 50 | Stack: # The stack goes here 51 | /* $end code-ysa */ 52 | /* $end code-yso */ 53 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/y86-code/abs-asum-jmp.ys: -------------------------------------------------------------------------------- 1 | # Modification of asum code to compute absolute values of entries. 2 | # This version uses a conditional jump 3 | # Execution begins at address 0 4 | .pos 0 5 | init: irmovl Stack, %esp # Set up Stack pointer 6 | irmovl Stack, %ebp # Set up base pointer 7 | jmp Main # Execute main program 8 | 9 | # Array of 4 elements 10 | .align 4 11 | array: .long 0x0000000d 12 | .long 0xffffff40 # -0xc0 13 | .long 0x00000b00 14 | .long 0xffff6000 # -0xa0000 15 | 16 | Main: irmovl $4,%eax 17 | pushl %eax # Push 4 18 | irmovl array,%edx 19 | pushl %edx # Push array 20 | call AbsSum # Sum(array, 4) 21 | halt 22 | 23 | /* $begin abs-sum-jmp-ys 0 */ 24 | # int AbsSum(int *Start, int Count) 25 | AbsSum: 26 | pushl %ebp 27 | rrmovl %esp,%ebp 28 | mrmovl 8(%ebp),%ecx # ecx = Start 29 | mrmovl 12(%ebp),%edx # edx = Count 30 | irmovl $0, %eax # sum = 0 31 | andl %edx,%edx 32 | je End 33 | Loop: 34 | mrmovl (%ecx),%esi # get x = *Start 35 | irmovl $0,%edi # 0 36 | subl %esi,%edi # -x 37 | jle Pos # Skip if -x <= 0 38 | rrmovl %edi,%esi # x = -x 39 | Pos: 40 | addl %esi,%eax # add x to sum 41 | irmovl $4,%ebx # 42 | addl %ebx,%ecx # Start++ 43 | irmovl $-1,%ebx # 44 | addl %ebx,%edx # Count-- 45 | jne Loop # Stop when 0 46 | End: 47 | popl %ebp 48 | ret 49 | /* $end abs-sum-jmp-ys 0 */ 50 | .pos 0x100 51 | Stack: # The stack goes here 52 | /* $end code-ysa */ 53 | /* $end code-yso */ 54 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/y86-code/asum.ys: -------------------------------------------------------------------------------- 1 | /* $begin code-yso */ 2 | /* $begin code-ysa */ 3 | # Execution begins at address 0 4 | .pos 0 5 | init: irmovl Stack, %esp # Set up stack pointer 6 | irmovl Stack, %ebp # Set up base pointer 7 | call Main # Execute main program 8 | halt # Terminate program 9 | 10 | # Array of 4 elements 11 | .align 4 12 | array: .long 0xd 13 | .long 0xc0 14 | .long 0xb00 15 | .long 0xa000 16 | 17 | Main: pushl %ebp 18 | rrmovl %esp,%ebp 19 | irmovl $4,%eax 20 | pushl %eax # Push 4 21 | irmovl array,%edx 22 | pushl %edx # Push array 23 | call Sum # Sum(array, 4) 24 | rrmovl %ebp,%esp 25 | popl %ebp 26 | ret 27 | 28 | /* $begin sum-ys 0 */ 29 | # int Sum(int *Start, int Count) 30 | Sum: pushl %ebp 31 | rrmovl %esp,%ebp 32 | mrmovl 8(%ebp),%ecx # ecx = Start 33 | mrmovl 12(%ebp),%edx # edx = Count 34 | xorl %eax,%eax # sum = 0 35 | andl %edx,%edx # Set condition codes 36 | je End 37 | Loop: mrmovl (%ecx),%esi # get *Start 38 | addl %esi,%eax # add to sum 39 | irmovl $4,%ebx # 40 | addl %ebx,%ecx # Start++ 41 | irmovl $-1,%ebx # 42 | addl %ebx,%edx # Count-- 43 | jne Loop # Stop when 0 44 | End: rrmovl %ebp,%esp 45 | popl %ebp 46 | ret 47 | /* $end sum-ys 0 */ 48 | 49 | # The stack starts here and grows to lower addresses 50 | .pos 0x100 51 | Stack: 52 | /* $end code-ysa */ 53 | /* $end code-yso */ 54 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/y86-code/asumi.ys: -------------------------------------------------------------------------------- 1 | /* $begin code-yso */ 2 | /* $begin code-ysa */ 3 | # This version makes use of the iaddl instruction 4 | # Execution begins at address 0 5 | .pos 0 6 | init: irmovl Stack, %esp # Set up Stack pointer 7 | irmovl Stack, %ebp # Set up base pointer 8 | jmp Main # Execute main program 9 | 10 | # Array of 4 elements 11 | .align 4 12 | array: .long 0xd 13 | .long 0xc0 14 | .long 0xb00 15 | .long 0xa000 16 | 17 | Main: irmovl $4,%eax 18 | pushl %eax # Push 4 19 | irmovl array,%edx 20 | pushl %edx # Push array 21 | call Sum # Sum(array, 4) 22 | halt 23 | 24 | # int Sum(int *Start, int Count) 25 | Sum: pushl %ebp 26 | rrmovl %esp,%ebp 27 | mrmovl 8(%ebp),%ecx # ecx = Start 28 | mrmovl 12(%ebp),%edx # edx = Count 29 | irmovl $0, %eax # sum = 0 30 | andl %edx,%edx 31 | je End 32 | Loop: mrmovl (%ecx),%esi # get *Start 33 | addl %esi,%eax # add to sum 34 | iaddl $4,%ecx # Sum++ 35 | iaddl $-1,%edx # Count-- 36 | jne Loop # Stop when 0 37 | End: popl %ebp 38 | ret 39 | .pos 0x100 40 | Stack: # The stack goes here 41 | /* $end code-ysa */ 42 | /* $end code-yso */ 43 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/y86-code/asuml.ys: -------------------------------------------------------------------------------- 1 | /* $begin code-yso */ 2 | /* $begin code-ysa */ 3 | # Execution begins at address 0 4 | # This version uses a leave instruction 5 | .pos 0 6 | init: irmovl Stack, %esp # Set up Stack pointer 7 | irmovl Stack, %ebp # Set up base pointer 8 | jmp Main # Execute main program 9 | 10 | # Array of 4 elements 11 | .align 4 12 | array: .long 0xd 13 | .long 0xc0 14 | .long 0xb00 15 | .long 0xa000 16 | 17 | Main: irmovl $4,%eax 18 | pushl %eax # Push 4 19 | irmovl array,%edx 20 | pushl %edx # Push array 21 | call rSum # Sum(array, 4) 22 | halt 23 | 24 | # int Sum(int *Start, int Count) 25 | rSum: pushl %ebp 26 | rrmovl %esp,%ebp 27 | irmovl $20,%eax 28 | subl %eax,%esp 29 | pushl %ebx 30 | mrmovl 8(%ebp),%ebx 31 | mrmovl 12(%ebp),%eax 32 | andl %eax,%eax 33 | jle L38 34 | irmovl $-8,%edx 35 | addl %edx,%esp 36 | irmovl $-1,%edx 37 | addl %edx,%eax 38 | pushl %eax 39 | irmovl $4,%edx 40 | rrmovl %ebx,%eax 41 | addl %edx,%eax 42 | pushl %eax 43 | call rSum 44 | mrmovl (%ebx),%edx 45 | addl %edx,%eax 46 | jmp L39 47 | L38: xorl %eax,%eax 48 | L39: mrmovl -24(%ebp),%ebx 49 | leave 50 | ret 51 | 52 | .pos 0x400 53 | Stack: # The stack goes here 54 | /* $end code-ysa */ 55 | /* $end code-yso */ 56 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/y86-code/asumr.ys: -------------------------------------------------------------------------------- 1 | # Execution begins at address 0 2 | .pos 0 3 | init: irmovl Stack, %esp # Set up Stack pointer 4 | irmovl Stack, %ebp # Set up base pointer 5 | jmp Main # Execute main program 6 | 7 | # Array of 4 elements 8 | .align 4 9 | array: .long 0xd 10 | .long 0xc0 11 | .long 0xb00 12 | .long 0xa000 13 | 14 | Main: irmovl $4,%eax 15 | pushl %eax # Push 4 16 | irmovl array,%edx 17 | pushl %edx # Push array 18 | call rSum # Sum(array, 4) 19 | halt 20 | 21 | /* $begin rsum-ys */ 22 | # int Sum(int *Start, int Count) 23 | rSum: pushl %ebp 24 | rrmovl %esp,%ebp 25 | pushl %ebx # Save value of %ebx 26 | mrmovl 8(%ebp),%ebx # Get Start 27 | mrmovl 12(%ebp),%eax # Get Count 28 | andl %eax,%eax # Test value of Count 29 | jle L38 # If <= 0, goto zreturn 30 | irmovl $-1,%edx 31 | addl %edx,%eax # Count-- 32 | pushl %eax # Push Count 33 | irmovl $4,%edx 34 | rrmovl %ebx,%eax 35 | addl %edx,%eax 36 | pushl %eax # Push Start+1 37 | call rSum # Sum(Start+1, Count-1) 38 | mrmovl (%ebx),%edx 39 | addl %edx,%eax # Add *Start 40 | jmp L39 # goto done 41 | L38: xorl %eax,%eax # zreturn: 42 | L39: mrmovl -4(%ebp),%ebx # done: Restore %ebx 43 | rrmovl %ebp,%esp # Deallocate stack frame 44 | popl %ebp # Restore %ebp 45 | ret 46 | /* $end rsum-ys */ 47 | .pos 0x400 48 | Stack: # The stack goes here 49 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/y86-code/cjr.ys: -------------------------------------------------------------------------------- 1 | # /* $begin cjr-ys */ 2 | # Code to generate a combination of not-taken branch and ret 3 | irmovl Stack, %esp 4 | irmovl rtnp,%eax 5 | pushl %eax # Set up return pointer 6 | xorl %eax,%eax # Set Z condition code 7 | jne target # Not taken (First part of combination) 8 | irmovl $1,%eax # Should execute this 9 | halt 10 | target: ret # Second part of combination 11 | irmovl $2,%ebx # Should not execute this 12 | halt 13 | rtnp: irmovl $3,%edx # Should not execute this 14 | halt 15 | .pos 0x40 16 | Stack: 17 | # /* $end cjr-ys */ 18 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/y86-code/j-cc.ys: -------------------------------------------------------------------------------- 1 | irmovl $1, %esi 2 | irmovl $2, %edi 3 | irmovl $4, %ebp 4 | irmovl $-32, %eax 5 | irmovl $64, %edx 6 | subl %edx,%eax 7 | je target 8 | nop 9 | halt 10 | target: 11 | addl %esi,%edx 12 | nop 13 | nop 14 | nop 15 | halt 16 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/y86-code/poptest.ys: -------------------------------------------------------------------------------- 1 | # Test of Pop semantics for Y86 2 | irmovl $0x100,%esp # Initialize stack pointer 3 | irmovl $0xABCD,%eax 4 | pushl %eax # Put known value on stack 5 | popl %esp # Either get 0xABCD, or 0xfc 6 | halt 7 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/y86-code/prog1.ys: -------------------------------------------------------------------------------- 1 | # prog1: Pad with 3 nop's 2 | irmovl $10,%edx 3 | irmovl $3,%eax 4 | nop 5 | nop 6 | nop 7 | addl %edx,%eax 8 | halt 9 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/y86-code/prog10.ys: -------------------------------------------------------------------------------- 1 | # prog10 2 | irmovl $1,%eax 3 | xorl %esp,%esp # Set stack pointer to 0 and CC to 100 4 | pushl %eax # Attempt to write to 0xfffffffc 5 | addl %eax,%eax # (Should not be executed) Would set CC to 000 6 | irmovl $2, %eax # Not executed 7 | irmovl $3, %eax # Not executed 8 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/y86-code/prog2.ys: -------------------------------------------------------------------------------- 1 | # prog2: Pad with 2 nop's 2 | irmovl $10,%edx 3 | irmovl $3,%eax 4 | nop 5 | nop 6 | addl %edx,%eax 7 | halt 8 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/y86-code/prog3.ys: -------------------------------------------------------------------------------- 1 | # prog3: Pad with 1 nop 2 | irmovl $10,%edx 3 | irmovl $3,%eax 4 | nop 5 | addl %edx,%eax 6 | halt 7 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/y86-code/prog4.ys: -------------------------------------------------------------------------------- 1 | # prog4: No padding 2 | irmovl $10,%edx 3 | irmovl $3,%eax 4 | addl %edx,%eax 5 | halt 6 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/y86-code/prog5.ys: -------------------------------------------------------------------------------- 1 | # prog5: Load/use hazard 2 | irmovl $128,%edx 3 | irmovl $3,%ecx 4 | rmmovl %ecx, 0(%edx) 5 | irmovl $10,%ebx 6 | mrmovl 0(%edx), %eax # Load %eax 7 | addl %ebx,%eax # Use %eax 8 | halt 9 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/y86-code/prog6.ys: -------------------------------------------------------------------------------- 1 | # prog6: Forwarding Priority 2 | irmovl $10,%edx 3 | irmovl $3,%edx 4 | rrmovl %edx,%eax 5 | halt 6 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/y86-code/prog7.ys: -------------------------------------------------------------------------------- 1 | # Demonstration of return 2 | # /* $begin prog7-ys */ 3 | # prog7 4 | irmovl Stack,%esp # Initialize stack pointer 5 | call Proc # procedure call 6 | irmovl $10,%edx # return point 7 | halt 8 | .pos 0x20 9 | Proc: # Proc: 10 | ret # return immediately 11 | rrmovl %edx,%ebx # not executed 12 | .pos 0x30 13 | Stack: # Stack: Stack pointer 14 | # /* $end prog7-ys */ 15 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/y86-code/prog8.ys: -------------------------------------------------------------------------------- 1 | # Demonstrate branch cancellation 2 | # /* $begin prog8-ys */ 3 | # prog8 4 | xorl %eax,%eax 5 | jne target # Not taken 6 | irmovl $1, %eax # Fall through 7 | halt 8 | target: 9 | irmovl $2, %edx # Target 10 | irmovl $3, %ebx # Target+1 11 | # /* $end prog8-ys */ 12 | halt 13 | 14 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/y86-code/prog9.ys: -------------------------------------------------------------------------------- 1 | # Exception handling 2 | # /* $begin prog9-yo */ 3 | xorl %eax,%eax 4 | jne Target # Not taken 5 | irmovl $1, %eax # Fall through 6 | halt 7 | Target: 8 | .byte 0xFF # Invalid instruction code 9 | # /* $end prog9-yo */ 10 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/y86-code/pushquestion.ys: -------------------------------------------------------------------------------- 1 | # Assembly Code to test semantics of pushl 2 | irmovl 0x100, %esp 3 | pushl %esp # Ambiguous 4 | popl %eax 5 | halt 6 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/y86-code/pushtest.ys: -------------------------------------------------------------------------------- 1 | # Test of Push semantics for Y86 2 | irmovl $0x100,%esp # Initialize stack pointer 3 | rrmovl %esp,%eax # Save stack pointer 4 | pushl %esp # Push the stack pointer (old or new?) 5 | popl %edx # Get it back 6 | subl %edx,%eax # Compute difference. Either 0 (old) or 4 (new). 7 | halt 8 | -------------------------------------------------------------------------------- /lab4-architecture-y86/sim/y86-code/ret-hazard.ys: -------------------------------------------------------------------------------- 1 | /* $begin ret-hazard-ys */ 2 | # Test instruction that modifies %esp followed by ret 3 | irmovl mem,%ebx 4 | mrmovl 0(%ebx),%esp # Sets %esp to point to return point 5 | ret # Returns to return point 6 | halt # 7 | rtnpt: irmovl $5,%esi # Return point 8 | halt 9 | .pos 0x40 10 | mem: .long stack # Holds desired stack pointer 11 | .pos 0x50 12 | stack: .long rtnpt # Top of stack: Holds return point 13 | /* $end ret-hazard-ys */ 14 | -------------------------------------------------------------------------------- /lab4-architecture-y86/simguide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YeXiaoRain/ICS_LAB_CMU_2016/dbef94921745c8c4429a64943dd982e7b6e4b34a/lab4-architecture-y86/simguide.pdf -------------------------------------------------------------------------------- /lab5-cache/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Student makefile for Cache Lab 3 | # Note: requires a 64-bit x86-64 system 4 | # 5 | CC = gcc 6 | CFLAGS = -g -Wall -Werror -std=c99 -m64 7 | 8 | all: csim test-trans tracegen 9 | # Generate a handin tar file each time you compile 10 | -tar -cvf ${USER}-handin.tar csim.c trans.c 11 | 12 | csim: csim.c cachelab.c cachelab.h 13 | $(CC) $(CFLAGS) -o csim csim.c cachelab.c -lm 14 | 15 | test-trans: test-trans.c trans.o cachelab.c cachelab.h 16 | $(CC) $(CFLAGS) -o test-trans test-trans.c cachelab.c trans.o 17 | 18 | tracegen: tracegen.c trans.o cachelab.c 19 | $(CC) $(CFLAGS) -O0 -o tracegen tracegen.c trans.o cachelab.c 20 | 21 | trans.o: trans.c 22 | $(CC) $(CFLAGS) -O0 -c trans.c 23 | 24 | # 25 | # Clean the src dirctory 26 | # 27 | clean: 28 | rm -rf *.o 29 | rm -f *.tar 30 | rm -f csim 31 | rm -f test-trans tracegen 32 | rm -f trace.all trace.f* trace.tmp 33 | rm -f .csim_results .marker 34 | -------------------------------------------------------------------------------- /lab5-cache/README: -------------------------------------------------------------------------------- 1 | This is the handout directory for the CS:APP Cache Lab. 2 | 3 | ************************ 4 | Running the autograders: 5 | ************************ 6 | 7 | Before running the autograders, compile your code: 8 | linux> make 9 | 10 | Check the correctness of your simulator: 11 | linux> ./test-csim 12 | 13 | Check the correctness and performance of your transpose functions: 14 | linux> ./test-trans -M 32 -N 32 15 | linux> ./test-trans -M 64 -N 64 16 | linux> ./test-trans -M 61 -N 67 17 | 18 | Check everything at once (this is the program that your instructor runs): 19 | linux> ./driver.py 20 | 21 | ****** 22 | Files: 23 | ****** 24 | 25 | # You will modifying and handing in these two files 26 | csim.c Your cache simulator 27 | trans.c Your transpose function 28 | 29 | # Tools for evaluating your simulator and transpose function 30 | Makefile Builds the simulator and tools 31 | README This file 32 | driver.py* The driver program, runs test-csim and test-trans 33 | cachelab.c Required helper functions 34 | cachelab.h Required header file 35 | csim-ref* The executable reference cache simulator 36 | test-csim* Tests your cache simulator 37 | test-trans.c Tests your transpose function 38 | tracegen.c Helper program used by test-trans 39 | traces/ Trace files used by test-csim.c 40 | -------------------------------------------------------------------------------- /lab5-cache/cachelab.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cachelab.c - Cache Lab helper functions 3 | */ 4 | #include 5 | #include 6 | #include 7 | #include "cachelab.h" 8 | #include 9 | 10 | trans_func_t func_list[MAX_TRANS_FUNCS]; 11 | int func_counter = 0; 12 | 13 | /* 14 | * printSummary - Summarize the cache simulation statistics. Student cache simulators 15 | * must call this function in order to be properly autograded. 16 | */ 17 | void printSummary(int hits, int misses, int evictions) 18 | { 19 | printf("hits:%d misses:%d evictions:%d\n", hits, misses, evictions); 20 | FILE* output_fp = fopen(".csim_results", "w"); 21 | assert(output_fp); 22 | fprintf(output_fp, "%d %d %d\n", hits, misses, evictions); 23 | fclose(output_fp); 24 | } 25 | 26 | /* 27 | * initMatrix - Initialize the given matrix 28 | */ 29 | void initMatrix(int M, int N, int A[N][M], int B[M][N]) 30 | { 31 | int i, j; 32 | srand(time(NULL)); 33 | for (i = 0; i < N; i++){ 34 | for (j = 0; j < M; j++){ 35 | // A[i][j] = i+j; /* The matrix created this way is symmetric */ 36 | A[i][j]=rand(); 37 | B[j][i]=rand(); 38 | } 39 | } 40 | } 41 | 42 | void randMatrix(int M, int N, int A[N][M]) { 43 | int i, j; 44 | srand(time(NULL)); 45 | for (i = 0; i < N; i++){ 46 | for (j = 0; j < M; j++){ 47 | // A[i][j] = i+j; /* The matrix created this way is symmetric */ 48 | A[i][j]=rand(); 49 | } 50 | } 51 | } 52 | 53 | /* 54 | * correctTrans - baseline transpose function used to evaluate correctness 55 | */ 56 | void correctTrans(int M, int N, int A[N][M], int B[M][N]) 57 | { 58 | int i, j, tmp; 59 | for (i = 0; i < N; i++){ 60 | for (j = 0; j < M; j++){ 61 | tmp = A[i][j]; 62 | B[j][i] = tmp; 63 | } 64 | } 65 | } 66 | 67 | 68 | 69 | /* 70 | * registerTransFunction - Add the given trans function into your list 71 | * of functions to be tested 72 | */ 73 | void registerTransFunction(void (*trans)(int M, int N, int[N][M], int[M][N]), 74 | char* desc) 75 | { 76 | func_list[func_counter].func_ptr = trans; 77 | func_list[func_counter].description = desc; 78 | func_list[func_counter].correct = 0; 79 | func_list[func_counter].num_hits = 0; 80 | func_list[func_counter].num_misses = 0; 81 | func_list[func_counter].num_evictions =0; 82 | func_counter++; 83 | } 84 | -------------------------------------------------------------------------------- /lab5-cache/cachelab.h: -------------------------------------------------------------------------------- 1 | /* 2 | * cachelab.h - Prototypes for Cache Lab helper functions 3 | */ 4 | 5 | #ifndef CACHELAB_TOOLS_H 6 | #define CACHELAB_TOOLS_H 7 | 8 | #define MAX_TRANS_FUNCS 100 9 | 10 | typedef struct trans_func{ 11 | void (*func_ptr)(int M,int N,int[N][M],int[M][N]); 12 | char* description; 13 | char correct; 14 | unsigned int num_hits; 15 | unsigned int num_misses; 16 | unsigned int num_evictions; 17 | } trans_func_t; 18 | 19 | /* 20 | * printSummary - This function provides a standard way for your cache 21 | * simulator * to display its final hit and miss statistics 22 | */ 23 | void printSummary(int hits, /* number of hits */ 24 | int misses, /* number of misses */ 25 | int evictions); /* number of evictions */ 26 | 27 | /* Fill the matrix with data */ 28 | void initMatrix(int M, int N, int A[N][M], int B[M][N]); 29 | 30 | /* The baseline trans function that produces correct results. */ 31 | void correctTrans(int M, int N, int A[N][M], int B[M][N]); 32 | 33 | /* Add the given function to the function list */ 34 | void registerTransFunction( 35 | void (*trans)(int M,int N,int[N][M],int[M][N]), char* desc); 36 | 37 | #endif /* CACHELAB_TOOLS_H */ 38 | -------------------------------------------------------------------------------- /lab5-cache/csim-ref: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YeXiaoRain/ICS_LAB_CMU_2016/dbef94921745c8c4429a64943dd982e7b6e4b34a/lab5-cache/csim-ref -------------------------------------------------------------------------------- /lab5-cache/csim.c: -------------------------------------------------------------------------------- 1 | #include "cachelab.h" 2 | 3 | int main() 4 | { 5 | printSummary(0, 0, 0); 6 | return 0; 7 | } 8 | -------------------------------------------------------------------------------- /lab5-cache/test-csim: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YeXiaoRain/ICS_LAB_CMU_2016/dbef94921745c8c4429a64943dd982e7b6e4b34a/lab5-cache/test-csim -------------------------------------------------------------------------------- /lab5-cache/tracegen.c: -------------------------------------------------------------------------------- 1 | /* 2 | * tracegen.c - Running the binary tracegen with valgrind produces 3 | * a memory trace of all of the registered transpose functions. 4 | * 5 | * The beginning and end of each registered transpose function's trace 6 | * is indicated by reading from "marker" addresses. These two marker 7 | * addresses are recorded in file for later use. 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include "cachelab.h" 16 | #include 17 | 18 | /* External variables declared in cachelab.c */ 19 | extern trans_func_t func_list[MAX_TRANS_FUNCS]; 20 | extern int func_counter; 21 | 22 | /* External function from trans.c */ 23 | extern void registerFunctions(); 24 | 25 | /* Markers used to bound trace regions of interest */ 26 | volatile char MARKER_START, MARKER_END; 27 | 28 | static int A[256][256]; 29 | static int B[256][256]; 30 | static int M; 31 | static int N; 32 | 33 | 34 | int validate(int fn,int M, int N, int A[N][M], int B[M][N]) { 35 | int C[M][N]; 36 | memset(C,0,sizeof(C)); 37 | correctTrans(M,N,A,C); 38 | for(int i=0;i 11 | #include "cachelab.h" 12 | 13 | int is_transpose(int M, int N, int A[N][M], int B[M][N]); 14 | 15 | /* 16 | * transpose_submit - This is the solution transpose function that you 17 | * will be graded on for Part B of the assignment. Do not change 18 | * the description string "Transpose submission", as the driver 19 | * searches for that string to identify the transpose function to 20 | * be graded. 21 | */ 22 | char transpose_submit_desc[] = "Transpose submission"; 23 | void transpose_submit(int M, int N, int A[N][M], int B[M][N]) 24 | { 25 | } 26 | 27 | /* 28 | * You can define additional transpose functions below. We've defined 29 | * a simple one below to help you get started. 30 | */ 31 | 32 | /* 33 | * trans - A simple baseline transpose function, not optimized for the cache. 34 | */ 35 | char trans_desc[] = "Simple row-wise scan transpose"; 36 | void trans(int M, int N, int A[N][M], int B[M][N]) 37 | { 38 | int i, j, tmp; 39 | 40 | for (i = 0; i < N; i++) { 41 | for (j = 0; j < M; j++) { 42 | tmp = A[i][j]; 43 | B[j][i] = tmp; 44 | } 45 | } 46 | 47 | } 48 | 49 | /* 50 | * registerFunctions - This function registers your transpose 51 | * functions with the driver. At runtime, the driver will 52 | * evaluate each of the registered functions and summarize their 53 | * performance. This is a handy way to experiment with different 54 | * transpose strategies. 55 | */ 56 | void registerFunctions() 57 | { 58 | /* Register your solution function */ 59 | registerTransFunction(transpose_submit, transpose_submit_desc); 60 | 61 | /* Register any additional transpose functions */ 62 | registerTransFunction(trans, trans_desc); 63 | 64 | } 65 | 66 | /* 67 | * is_transpose - This helper function checks if B is the transpose of 68 | * A. You can check the correctness of your transpose by calling 69 | * it before returning from the transpose function. 70 | */ 71 | int is_transpose(int M, int N, int A[N][M], int B[M][N]) 72 | { 73 | int i, j; 74 | 75 | for (i = 0; i < N; i++) { 76 | for (j = 0; j < M; ++j) { 77 | if (A[i][j] != B[j][i]) { 78 | return 0; 79 | } 80 | } 81 | } 82 | return 1; 83 | } 84 | 85 | -------------------------------------------------------------------------------- /lab6-performance/Makefile: -------------------------------------------------------------------------------- 1 | # Student's Makefile for the CS:APP Performance Lab 2 | TEAM = bovik 3 | VERSION = 1 4 | HANDINDIR = 5 | 6 | CC = gcc 7 | CFLAGS = -Wall -O2 -m32 8 | LIBS = -lm 9 | 10 | OBJS = driver.o kernels.o fcyc.o clock.o 11 | 12 | all: driver 13 | 14 | driver: $(OBJS) fcyc.h clock.h defs.h config.h 15 | $(CC) $(CFLAGS) $(OBJS) $(LIBS) -o driver 16 | 17 | handin: 18 | cp kernels.c $(HANDINDIR)/$(TEAM)-$(VERSION)-kernels.c 19 | 20 | clean: 21 | -rm -f $(OBJS) driver core *~ *.o 22 | 23 | 24 | -------------------------------------------------------------------------------- /lab6-performance/README: -------------------------------------------------------------------------------- 1 | ##################################################################### 2 | # CS:APP Performance Lab 3 | # 4 | # Student's Source Files 5 | # 6 | # Copyright (c) 2002, R. Bryant and D. O'Hallaron, All rights reserved. 7 | # May not be used, modified, or copied without permission. 8 | # 9 | ###################################################################### 10 | 11 | This directory contains the files you will need for the CS:APP 12 | Performance Lab. 13 | 14 | kernels.c 15 | This is the file you will be modifying and handing in. 16 | 17 | ######################################### 18 | # You shouldn't modify any of these files 19 | ######################################### 20 | driver.c 21 | This is the driver that tests the performance of all 22 | of the versions of the rotate and smooth kernels 23 | in your kernels.c file. 24 | 25 | config.h 26 | This is a site-specific configuration file that was created by 27 | your instructor for your system. 28 | 29 | defs.h 30 | Various definitions needed by kernels.c and driver.c 31 | 32 | clock.{c,h} 33 | fcyc.{c,h} 34 | These contain timing routines that measure the performance of your 35 | code with our k-best measurement scheme using IA32 cycle counters. 36 | 37 | Makefile: 38 | This is the makefile that builds the driver program. 39 | -------------------------------------------------------------------------------- /lab6-performance/clock.h: -------------------------------------------------------------------------------- 1 | /* Routines for using cycle counter */ 2 | 3 | /* Start the counter */ 4 | void start_counter(); 5 | 6 | /* Get # cycles since counter started */ 7 | double get_counter(); 8 | 9 | /* Measure overhead for counter */ 10 | double ovhd(); 11 | 12 | /* Determine clock rate of processor (using a default sleeptime) */ 13 | double mhz(int verbose); 14 | 15 | /* Determine clock rate of processor, having more control over accuracy */ 16 | double mhz_full(int verbose, int sleeptime); 17 | 18 | /** Special counters that compensate for timer interrupt overhead */ 19 | 20 | void start_comp_counter(); 21 | 22 | double get_comp_counter(); 23 | -------------------------------------------------------------------------------- /lab6-performance/config.h: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * config.h - Configuration data for the driver.c program. 3 | *********************************************************/ 4 | #ifndef _CONFIG_H_ 5 | #define _CONFIG_H_ 6 | 7 | /* 8 | * CPEs for the baseline (naive) version of the rotate function that 9 | * was handed out to the students. Rd is the measured CPE for a dxd 10 | * image. Run the driver.c program on your system to get these 11 | * numbers. 12 | */ 13 | #define R64 14.7 14 | #define R128 40.1 15 | #define R256 46.4 16 | #define R512 65.9 17 | #define R1024 94.5 18 | 19 | /* 20 | * CPEs for the baseline (naive) version of the smooth function that 21 | * was handed out to the students. Sd is the measure CPE for a dxd 22 | * image. Run the driver.c program on your system to get these 23 | * numbers. 24 | */ 25 | #define S32 695 26 | #define S64 698 27 | #define S128 702 28 | #define S256 717 29 | #define S512 722 30 | 31 | 32 | #endif /* _CONFIG_H_ */ 33 | -------------------------------------------------------------------------------- /lab6-performance/defs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * driver.h - Various definitions for the Performance Lab. 3 | * 4 | * DO NOT MODIFY ANYTHING IN THIS FILE 5 | */ 6 | #ifndef _DEFS_H_ 7 | #define _DEFS_H_ 8 | 9 | #include 10 | 11 | #define RIDX(i,j,n) ((i)*(n)+(j)) 12 | 13 | typedef struct { 14 | char *team; 15 | char *name1, *email1; 16 | char *name2, *email2; 17 | } team_t; 18 | 19 | extern team_t team; 20 | 21 | typedef struct { 22 | unsigned short red; 23 | unsigned short green; 24 | unsigned short blue; 25 | } pixel; 26 | 27 | typedef void (*lab_test_func) (int, pixel*, pixel*); 28 | 29 | void smooth(int, pixel *, pixel *); 30 | void rotate(int, pixel *, pixel *); 31 | 32 | void register_rotate_functions(void); 33 | void register_smooth_functions(void); 34 | void add_smooth_function(lab_test_func, char*); 35 | void add_rotate_function(lab_test_func, char*); 36 | 37 | #endif /* _DEFS_H_ */ 38 | 39 | -------------------------------------------------------------------------------- /lab6-performance/fcyc.h: -------------------------------------------------------------------------------- 1 | 2 | /* Fcyc measures the speed of any "test function." Such a function 3 | is passed a list of integer parameters, which it may interpret 4 | in any way it chooses. 5 | */ 6 | 7 | typedef void (*test_funct)(int *); 8 | typedef void (*test_funct_v)(void *); 9 | 10 | /* Compute number of cycles used by function f on given set of parameters */ 11 | double fcyc(test_funct f, int* params); 12 | double fcyc_v(test_funct_v f, void* params[]); 13 | 14 | /***********************************************************/ 15 | /* Set the various parameters used by measurement routines */ 16 | 17 | 18 | /* When set, will run code to clear cache before each measurement 19 | Default = 0 20 | */ 21 | void set_fcyc_clear_cache(int clear); 22 | 23 | /* Set size of cache to use when clearing cache 24 | Default = 1<<19 (512KB) 25 | */ 26 | void set_fcyc_cache_size(int bytes); 27 | 28 | /* Set size of cache block 29 | Default = 32 30 | */ 31 | void set_fcyc_cache_block(int bytes); 32 | 33 | /* When set, will attempt to compensate for timer interrupt overhead 34 | Default = 0 35 | */ 36 | void set_fcyc_compensate(int compensate); 37 | 38 | /* Value of K in K-best 39 | Default = 3 40 | */ 41 | void set_fcyc_k(int k); 42 | 43 | /* Maximum number of samples attempting to find K-best within some tolerance. 44 | When exceeded, just return best sample found. 45 | Default = 20 46 | */ 47 | void set_fcyc_maxsamples(int maxsamples); 48 | 49 | /* Tolerance required for K-best 50 | Default = 0.01 51 | */ 52 | void set_fcyc_epsilon(double epsilon); 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /lab7-shell/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for the CS:APP Shell Lab 2 | 3 | TEAM = NOBODY 4 | VERSION = 1 5 | HANDINDIR = /afs/cs/academic/class/15213-f02/L5/handin 6 | DRIVER = ./sdriver.pl 7 | TSH = ./tsh 8 | TSHREF = ./tshref 9 | TSHARGS = "-p" 10 | CC = gcc 11 | CFLAGS = -Wall -O2 12 | FILES = $(TSH) ./myspin ./mysplit ./mystop ./myint 13 | 14 | all: $(FILES) 15 | 16 | ################## 17 | # Handin your work 18 | ################## 19 | handin: 20 | cp tsh.c $(HANDINDIR)/$(TEAM)-$(VERSION)-tsh.c 21 | 22 | 23 | ################## 24 | # Regression tests 25 | ################## 26 | 27 | # Run tests using the student's shell program 28 | test01: 29 | $(DRIVER) -t trace01.txt -s $(TSH) -a $(TSHARGS) 30 | test02: 31 | $(DRIVER) -t trace02.txt -s $(TSH) -a $(TSHARGS) 32 | test03: 33 | $(DRIVER) -t trace03.txt -s $(TSH) -a $(TSHARGS) 34 | test04: 35 | $(DRIVER) -t trace04.txt -s $(TSH) -a $(TSHARGS) 36 | test05: 37 | $(DRIVER) -t trace05.txt -s $(TSH) -a $(TSHARGS) 38 | test06: 39 | $(DRIVER) -t trace06.txt -s $(TSH) -a $(TSHARGS) 40 | test07: 41 | $(DRIVER) -t trace07.txt -s $(TSH) -a $(TSHARGS) 42 | test08: 43 | $(DRIVER) -t trace08.txt -s $(TSH) -a $(TSHARGS) 44 | test09: 45 | $(DRIVER) -t trace09.txt -s $(TSH) -a $(TSHARGS) 46 | test10: 47 | $(DRIVER) -t trace10.txt -s $(TSH) -a $(TSHARGS) 48 | test11: 49 | $(DRIVER) -t trace11.txt -s $(TSH) -a $(TSHARGS) 50 | test12: 51 | $(DRIVER) -t trace12.txt -s $(TSH) -a $(TSHARGS) 52 | test13: 53 | $(DRIVER) -t trace13.txt -s $(TSH) -a $(TSHARGS) 54 | test14: 55 | $(DRIVER) -t trace14.txt -s $(TSH) -a $(TSHARGS) 56 | test15: 57 | $(DRIVER) -t trace15.txt -s $(TSH) -a $(TSHARGS) 58 | test16: 59 | $(DRIVER) -t trace16.txt -s $(TSH) -a $(TSHARGS) 60 | 61 | # Run the tests using the reference shell program 62 | rtest01: 63 | $(DRIVER) -t trace01.txt -s $(TSHREF) -a $(TSHARGS) 64 | rtest02: 65 | $(DRIVER) -t trace02.txt -s $(TSHREF) -a $(TSHARGS) 66 | rtest03: 67 | $(DRIVER) -t trace03.txt -s $(TSHREF) -a $(TSHARGS) 68 | rtest04: 69 | $(DRIVER) -t trace04.txt -s $(TSHREF) -a $(TSHARGS) 70 | rtest05: 71 | $(DRIVER) -t trace05.txt -s $(TSHREF) -a $(TSHARGS) 72 | rtest06: 73 | $(DRIVER) -t trace06.txt -s $(TSHREF) -a $(TSHARGS) 74 | rtest07: 75 | $(DRIVER) -t trace07.txt -s $(TSHREF) -a $(TSHARGS) 76 | rtest08: 77 | $(DRIVER) -t trace08.txt -s $(TSHREF) -a $(TSHARGS) 78 | rtest09: 79 | $(DRIVER) -t trace09.txt -s $(TSHREF) -a $(TSHARGS) 80 | rtest10: 81 | $(DRIVER) -t trace10.txt -s $(TSHREF) -a $(TSHARGS) 82 | rtest11: 83 | $(DRIVER) -t trace11.txt -s $(TSHREF) -a $(TSHARGS) 84 | rtest12: 85 | $(DRIVER) -t trace12.txt -s $(TSHREF) -a $(TSHARGS) 86 | rtest13: 87 | $(DRIVER) -t trace13.txt -s $(TSHREF) -a $(TSHARGS) 88 | rtest14: 89 | $(DRIVER) -t trace14.txt -s $(TSHREF) -a $(TSHARGS) 90 | rtest15: 91 | $(DRIVER) -t trace15.txt -s $(TSHREF) -a $(TSHARGS) 92 | rtest16: 93 | $(DRIVER) -t trace16.txt -s $(TSHREF) -a $(TSHARGS) 94 | 95 | 96 | # clean up 97 | clean: 98 | rm -f $(FILES) *.o *~ 99 | 100 | 101 | -------------------------------------------------------------------------------- /lab7-shell/README: -------------------------------------------------------------------------------- 1 | ################ 2 | CS:APP Shell Lab 3 | ################ 4 | 5 | Files: 6 | 7 | Makefile # Compiles your shell program and runs the tests 8 | README # This file 9 | tsh.c # The shell program that you will write and hand in 10 | tshref # The reference shell binary. 11 | 12 | # The remaining files are used to test your shell 13 | sdriver.pl # The trace-driven shell driver 14 | trace*.txt # The 15 trace files that control the shell driver 15 | tshref.out # Example output of the reference shell on all 15 traces 16 | 17 | # Little C programs that are called by the trace files 18 | myspin.c # Takes argument and spins for seconds 19 | mysplit.c # Forks a child that spins for seconds 20 | mystop.c # Spins for seconds and sends SIGTSTP to itself 21 | myint.c # Spins for seconds and sends SIGINT to itself 22 | 23 | -------------------------------------------------------------------------------- /lab7-shell/myint.c: -------------------------------------------------------------------------------- 1 | /* 2 | * myint.c - Another handy routine for testing your tiny shell 3 | * 4 | * usage: myint 5 | * Sleeps for seconds and sends SIGINT to itself. 6 | * 7 | */ 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | int main(int argc, char **argv) 16 | { 17 | int i, secs; 18 | pid_t pid; 19 | 20 | if (argc != 2) { 21 | fprintf(stderr, "Usage: %s \n", argv[0]); 22 | exit(0); 23 | } 24 | secs = atoi(argv[1]); 25 | 26 | for (i=0; i < secs; i++) 27 | sleep(1); 28 | 29 | pid = getpid(); 30 | 31 | if (kill(pid, SIGINT) < 0) 32 | fprintf(stderr, "kill (int) error"); 33 | 34 | exit(0); 35 | 36 | } 37 | -------------------------------------------------------------------------------- /lab7-shell/myspin.c: -------------------------------------------------------------------------------- 1 | /* 2 | * myspin.c - A handy program for testing your tiny shell 3 | * 4 | * usage: myspin 5 | * Sleeps for seconds in 1-second chunks. 6 | * 7 | */ 8 | #include 9 | #include 10 | #include 11 | 12 | int main(int argc, char **argv) 13 | { 14 | int i, secs; 15 | 16 | if (argc != 2) { 17 | fprintf(stderr, "Usage: %s \n", argv[0]); 18 | exit(0); 19 | } 20 | secs = atoi(argv[1]); 21 | for (i=0; i < secs; i++) 22 | sleep(1); 23 | exit(0); 24 | } 25 | -------------------------------------------------------------------------------- /lab7-shell/mysplit.c: -------------------------------------------------------------------------------- 1 | /* 2 | * mysplit.c - Another handy routine for testing your tiny shell 3 | * 4 | * usage: mysplit 5 | * Fork a child that spins for seconds in 1-second chunks. 6 | */ 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | int main(int argc, char **argv) 15 | { 16 | int i, secs; 17 | 18 | if (argc != 2) { 19 | fprintf(stderr, "Usage: %s \n", argv[0]); 20 | exit(0); 21 | } 22 | secs = atoi(argv[1]); 23 | 24 | 25 | if (fork() == 0) { /* child */ 26 | for (i=0; i < secs; i++) 27 | sleep(1); 28 | exit(0); 29 | } 30 | 31 | /* parent waits for child to terminate */ 32 | wait(NULL); 33 | 34 | exit(0); 35 | } 36 | -------------------------------------------------------------------------------- /lab7-shell/mystop.c: -------------------------------------------------------------------------------- 1 | /* 2 | * mystop.c - Another handy routine for testing your tiny shell 3 | * 4 | * usage: mystop 5 | * Sleeps for seconds and sends SIGTSTP to itself. 6 | * 7 | */ 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | int main(int argc, char **argv) 16 | { 17 | int i, secs; 18 | pid_t pid; 19 | 20 | if (argc != 2) { 21 | fprintf(stderr, "Usage: %s \n", argv[0]); 22 | exit(0); 23 | } 24 | secs = atoi(argv[1]); 25 | 26 | for (i=0; i < secs; i++) 27 | sleep(1); 28 | 29 | pid = getpid(); 30 | 31 | if (kill(-pid, SIGTSTP) < 0) 32 | fprintf(stderr, "kill (tstp) error"); 33 | 34 | exit(0); 35 | 36 | } 37 | -------------------------------------------------------------------------------- /lab7-shell/trace01.txt: -------------------------------------------------------------------------------- 1 | # 2 | # trace01.txt - Properly terminate on EOF. 3 | # 4 | CLOSE 5 | WAIT 6 | -------------------------------------------------------------------------------- /lab7-shell/trace02.txt: -------------------------------------------------------------------------------- 1 | # 2 | # trace02.txt - Process builtin quit command. 3 | # 4 | quit 5 | WAIT 6 | -------------------------------------------------------------------------------- /lab7-shell/trace03.txt: -------------------------------------------------------------------------------- 1 | # 2 | # trace03.txt - Run a foreground job. 3 | # 4 | /bin/echo tsh> quit 5 | quit 6 | -------------------------------------------------------------------------------- /lab7-shell/trace04.txt: -------------------------------------------------------------------------------- 1 | # 2 | # trace04.txt - Run a background job. 3 | # 4 | /bin/echo -e tsh> ./myspin 1 \046 5 | ./myspin 1 & 6 | -------------------------------------------------------------------------------- /lab7-shell/trace05.txt: -------------------------------------------------------------------------------- 1 | # 2 | # trace05.txt - Process jobs builtin command. 3 | # 4 | /bin/echo -e tsh> ./myspin 2 \046 5 | ./myspin 2 & 6 | 7 | /bin/echo -e tsh> ./myspin 3 \046 8 | ./myspin 3 & 9 | 10 | /bin/echo tsh> jobs 11 | jobs 12 | -------------------------------------------------------------------------------- /lab7-shell/trace06.txt: -------------------------------------------------------------------------------- 1 | # 2 | # trace06.txt - Forward SIGINT to foreground job. 3 | # 4 | /bin/echo -e tsh> ./myspin 4 5 | ./myspin 4 6 | 7 | SLEEP 2 8 | INT 9 | -------------------------------------------------------------------------------- /lab7-shell/trace07.txt: -------------------------------------------------------------------------------- 1 | # 2 | # trace07.txt - Forward SIGINT only to foreground job. 3 | # 4 | /bin/echo -e tsh> ./myspin 4 \046 5 | ./myspin 4 & 6 | 7 | /bin/echo -e tsh> ./myspin 5 8 | ./myspin 5 9 | 10 | SLEEP 2 11 | INT 12 | 13 | /bin/echo tsh> jobs 14 | jobs 15 | -------------------------------------------------------------------------------- /lab7-shell/trace08.txt: -------------------------------------------------------------------------------- 1 | # 2 | # trace08.txt - Forward SIGTSTP only to foreground job. 3 | # 4 | /bin/echo -e tsh> ./myspin 4 \046 5 | ./myspin 4 & 6 | 7 | /bin/echo -e tsh> ./myspin 5 8 | ./myspin 5 9 | 10 | SLEEP 2 11 | TSTP 12 | 13 | /bin/echo tsh> jobs 14 | jobs 15 | -------------------------------------------------------------------------------- /lab7-shell/trace09.txt: -------------------------------------------------------------------------------- 1 | # 2 | # trace09.txt - Process bg builtin command 3 | # 4 | /bin/echo -e tsh> ./myspin 4 \046 5 | ./myspin 4 & 6 | 7 | /bin/echo -e tsh> ./myspin 5 8 | ./myspin 5 9 | 10 | SLEEP 2 11 | TSTP 12 | 13 | /bin/echo tsh> jobs 14 | jobs 15 | 16 | /bin/echo tsh> bg %2 17 | bg %2 18 | 19 | /bin/echo tsh> jobs 20 | jobs 21 | -------------------------------------------------------------------------------- /lab7-shell/trace10.txt: -------------------------------------------------------------------------------- 1 | # 2 | # trace10.txt - Process fg builtin command. 3 | # 4 | /bin/echo -e tsh> ./myspin 4 \046 5 | ./myspin 4 & 6 | 7 | SLEEP 1 8 | /bin/echo tsh> fg %1 9 | fg %1 10 | 11 | SLEEP 1 12 | TSTP 13 | 14 | /bin/echo tsh> jobs 15 | jobs 16 | 17 | /bin/echo tsh> fg %1 18 | fg %1 19 | 20 | /bin/echo tsh> jobs 21 | jobs 22 | 23 | -------------------------------------------------------------------------------- /lab7-shell/trace11.txt: -------------------------------------------------------------------------------- 1 | # 2 | # trace11.txt - Forward SIGINT to every process in foreground process group 3 | # 4 | /bin/echo -e tsh> ./mysplit 4 5 | ./mysplit 4 6 | 7 | SLEEP 2 8 | INT 9 | 10 | /bin/echo tsh> /bin/ps a 11 | /bin/ps a 12 | 13 | -------------------------------------------------------------------------------- /lab7-shell/trace12.txt: -------------------------------------------------------------------------------- 1 | # 2 | # trace12.txt - Forward SIGTSTP to every process in foreground process group 3 | # 4 | /bin/echo -e tsh> ./mysplit 4 5 | ./mysplit 4 6 | 7 | SLEEP 2 8 | TSTP 9 | 10 | /bin/echo tsh> jobs 11 | jobs 12 | 13 | /bin/echo tsh> /bin/ps a 14 | /bin/ps a 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /lab7-shell/trace13.txt: -------------------------------------------------------------------------------- 1 | # 2 | # trace13.txt - Restart every stopped process in process group 3 | # 4 | /bin/echo -e tsh> ./mysplit 4 5 | ./mysplit 4 6 | 7 | SLEEP 2 8 | TSTP 9 | 10 | /bin/echo tsh> jobs 11 | jobs 12 | 13 | /bin/echo tsh> /bin/ps a 14 | /bin/ps a 15 | 16 | /bin/echo tsh> fg %1 17 | fg %1 18 | 19 | /bin/echo tsh> /bin/ps a 20 | /bin/ps a 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /lab7-shell/trace14.txt: -------------------------------------------------------------------------------- 1 | # 2 | # trace14.txt - Simple error handling 3 | # 4 | /bin/echo tsh> ./bogus 5 | ./bogus 6 | 7 | /bin/echo -e tsh> ./myspin 4 \046 8 | ./myspin 4 & 9 | 10 | /bin/echo tsh> fg 11 | fg 12 | 13 | /bin/echo tsh> bg 14 | bg 15 | 16 | /bin/echo tsh> fg a 17 | fg a 18 | 19 | /bin/echo tsh> bg a 20 | bg a 21 | 22 | /bin/echo tsh> fg 9999999 23 | fg 9999999 24 | 25 | /bin/echo tsh> bg 9999999 26 | bg 9999999 27 | 28 | /bin/echo tsh> fg %2 29 | fg %2 30 | 31 | /bin/echo tsh> fg %1 32 | fg %1 33 | 34 | SLEEP 2 35 | TSTP 36 | 37 | /bin/echo tsh> bg %2 38 | bg %2 39 | 40 | /bin/echo tsh> bg %1 41 | bg %1 42 | 43 | /bin/echo tsh> jobs 44 | jobs 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /lab7-shell/trace15.txt: -------------------------------------------------------------------------------- 1 | # 2 | # trace15.txt - Putting it all together 3 | # 4 | 5 | /bin/echo tsh> ./bogus 6 | ./bogus 7 | 8 | /bin/echo tsh> ./myspin 10 9 | ./myspin 10 10 | 11 | SLEEP 2 12 | INT 13 | 14 | /bin/echo -e tsh> ./myspin 3 \046 15 | ./myspin 3 & 16 | 17 | /bin/echo -e tsh> ./myspin 4 \046 18 | ./myspin 4 & 19 | 20 | /bin/echo tsh> jobs 21 | jobs 22 | 23 | /bin/echo tsh> fg %1 24 | fg %1 25 | 26 | SLEEP 2 27 | TSTP 28 | 29 | /bin/echo tsh> jobs 30 | jobs 31 | 32 | /bin/echo tsh> bg %3 33 | bg %3 34 | 35 | /bin/echo tsh> bg %1 36 | bg %1 37 | 38 | /bin/echo tsh> jobs 39 | jobs 40 | 41 | /bin/echo tsh> fg %1 42 | fg %1 43 | 44 | /bin/echo tsh> quit 45 | quit 46 | 47 | -------------------------------------------------------------------------------- /lab7-shell/trace16.txt: -------------------------------------------------------------------------------- 1 | # 2 | # trace16.txt - Tests whether the shell can handle SIGTSTP and SIGINT 3 | # signals that come from other processes instead of the terminal. 4 | # 5 | 6 | /bin/echo tsh> ./mystop 2 7 | ./mystop 2 8 | 9 | SLEEP 3 10 | 11 | /bin/echo tsh> jobs 12 | jobs 13 | 14 | /bin/echo tsh> ./myint 2 15 | ./myint 2 16 | 17 | -------------------------------------------------------------------------------- /lab7-shell/tshref: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YeXiaoRain/ICS_LAB_CMU_2016/dbef94921745c8c4429a64943dd982e7b6e4b34a/lab7-shell/tshref -------------------------------------------------------------------------------- /lab8-malloc/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Students' Makefile for the Malloc Lab 3 | # 4 | TEAM = bovik 5 | VERSION = 1 6 | HANDINDIR = /afs/cs.cmu.edu/academic/class/15213-f01/malloclab/handin 7 | 8 | CC = gcc 9 | CFLAGS = -Wall -O2 -m32 10 | 11 | OBJS = mdriver.o mm.o memlib.o fsecs.o fcyc.o clock.o ftimer.o 12 | 13 | mdriver: $(OBJS) 14 | $(CC) $(CFLAGS) -o mdriver $(OBJS) 15 | 16 | mdriver.o: mdriver.c fsecs.h fcyc.h clock.h memlib.h config.h mm.h 17 | memlib.o: memlib.c memlib.h 18 | mm.o: mm.c mm.h memlib.h 19 | fsecs.o: fsecs.c fsecs.h config.h 20 | fcyc.o: fcyc.c fcyc.h 21 | ftimer.o: ftimer.c ftimer.h config.h 22 | clock.o: clock.c clock.h 23 | 24 | handin: 25 | cp mm.c $(HANDINDIR)/$(TEAM)-$(VERSION)-mm.c 26 | 27 | clean: 28 | rm -f *~ *.o mdriver 29 | 30 | 31 | -------------------------------------------------------------------------------- /lab8-malloc/README: -------------------------------------------------------------------------------- 1 | ##################################################################### 2 | # CS:APP Malloc Lab 3 | # Handout files for students 4 | # 5 | # Copyright (c) 2002, R. Bryant and D. O'Hallaron, All rights reserved. 6 | # May not be used, modified, or copied without permission. 7 | # 8 | ###################################################################### 9 | 10 | *********** 11 | Main Files: 12 | *********** 13 | 14 | mm.{c,h} 15 | Your solution malloc package. mm.c is the file that you 16 | will be handing in, and is the only file you should modify. 17 | 18 | mdriver.c 19 | The malloc driver that tests your mm.c file 20 | 21 | short{1,2}-bal.rep 22 | Two tiny tracefiles to help you get started. 23 | 24 | Makefile 25 | Builds the driver 26 | 27 | ********************************** 28 | Other support files for the driver 29 | ********************************** 30 | 31 | config.h Configures the malloc lab driver 32 | fsecs.{c,h} Wrapper function for the different timer packages 33 | clock.{c,h} Routines for accessing the Pentium and Alpha cycle counters 34 | fcyc.{c,h} Timer functions based on cycle counters 35 | ftimer.{c,h} Timer functions based on interval timers and gettimeofday() 36 | memlib.{c,h} Models the heap and sbrk function 37 | 38 | ******************************* 39 | Building and running the driver 40 | ******************************* 41 | To build the driver, type "make" to the shell. 42 | 43 | To run the driver on a tiny test trace: 44 | 45 | unix> mdriver -V -f short1-bal.rep 46 | 47 | The -V option prints out helpful tracing and summary information. 48 | 49 | To get a list of the driver flags: 50 | 51 | unix> mdriver -h 52 | 53 | -------------------------------------------------------------------------------- /lab8-malloc/clock.h: -------------------------------------------------------------------------------- 1 | /* Routines for using cycle counter */ 2 | 3 | /* Start the counter */ 4 | void start_counter(); 5 | 6 | /* Get # cycles since counter started */ 7 | double get_counter(); 8 | 9 | /* Measure overhead for counter */ 10 | double ovhd(); 11 | 12 | /* Determine clock rate of processor (using a default sleeptime) */ 13 | double mhz(int verbose); 14 | 15 | /* Determine clock rate of processor, having more control over accuracy */ 16 | double mhz_full(int verbose, int sleeptime); 17 | 18 | /** Special counters that compensate for timer interrupt overhead */ 19 | 20 | void start_comp_counter(); 21 | 22 | double get_comp_counter(); 23 | -------------------------------------------------------------------------------- /lab8-malloc/config.h: -------------------------------------------------------------------------------- 1 | #ifndef __CONFIG_H_ 2 | #define __CONFIG_H_ 3 | 4 | /* 5 | * config.h - malloc lab configuration file 6 | * 7 | * Copyright (c) 2002, R. Bryant and D. O'Hallaron, All rights reserved. 8 | * May not be used, modified, or copied without permission. 9 | */ 10 | 11 | /* 12 | * This is the default path where the driver will look for the 13 | * default tracefiles. You can override it at runtime with the -t flag. 14 | */ 15 | #define TRACEDIR "/afs/cs/project/ics2/im/labs/malloclab/traces/" 16 | 17 | /* 18 | * This is the list of default tracefiles in TRACEDIR that the driver 19 | * will use for testing. Modify this if you want to add or delete 20 | * traces from the driver's test suite. For example, if you don't want 21 | * your students to implement realloc, you can delete the last two 22 | * traces. 23 | */ 24 | #define DEFAULT_TRACEFILES \ 25 | "amptjp-bal.rep",\ 26 | "cccp-bal.rep",\ 27 | "cp-decl-bal.rep",\ 28 | "expr-bal.rep",\ 29 | "coalescing-bal.rep",\ 30 | "random-bal.rep",\ 31 | "random2-bal.rep",\ 32 | "binary-bal.rep",\ 33 | "binary2-bal.rep",\ 34 | "realloc-bal.rep",\ 35 | "realloc2-bal.rep" 36 | 37 | /* 38 | * This constant gives the estimated performance of the libc malloc 39 | * package using our traces on some reference system, typically the 40 | * same kind of system the students use. Its purpose is to cap the 41 | * contribution of throughput to the performance index. Once the 42 | * students surpass the AVG_LIBC_THRUPUT, they get no further benefit 43 | * to their score. This deters students from building extremely fast, 44 | * but extremely stupid malloc packages. 45 | */ 46 | #define AVG_LIBC_THRUPUT 600E3 /* 600 Kops/sec */ 47 | 48 | /* 49 | * This constant determines the contributions of space utilization 50 | * (UTIL_WEIGHT) and throughput (1 - UTIL_WEIGHT) to the performance 51 | * index. 52 | */ 53 | #define UTIL_WEIGHT .60 54 | 55 | /* 56 | * Alignment requirement in bytes (either 4 or 8) 57 | */ 58 | #define ALIGNMENT 8 59 | 60 | /* 61 | * Maximum heap size in bytes 62 | */ 63 | #define MAX_HEAP (20*(1<<20)) /* 20 MB */ 64 | 65 | /***************************************************************************** 66 | * Set exactly one of these USE_xxx constants to "1" to select a timing method 67 | *****************************************************************************/ 68 | #define USE_FCYC 0 /* cycle counter w/K-best scheme (x86 & Alpha only) */ 69 | #define USE_ITIMER 0 /* interval timer (any Unix box) */ 70 | #define USE_GETTOD 1 /* gettimeofday (any Unix box) */ 71 | 72 | #endif /* __CONFIG_H */ 73 | -------------------------------------------------------------------------------- /lab8-malloc/fcyc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * fcyc.h - prototypes for the routines in fcyc.c that estimate the 3 | * time in CPU cycles used by a test function f 4 | * 5 | * Copyright (c) 2002, R. Bryant and D. O'Hallaron, All rights reserved. 6 | * May not be used, modified, or copied without permission. 7 | * 8 | */ 9 | 10 | /* The test function takes a generic pointer as input */ 11 | typedef void (*test_funct)(void *); 12 | 13 | /* Compute number of cycles used by test function f */ 14 | double fcyc(test_funct f, void* argp); 15 | 16 | /********************************************************* 17 | * Set the various parameters used by measurement routines 18 | *********************************************************/ 19 | 20 | /* 21 | * set_fcyc_clear_cache - When set, will run code to clear cache 22 | * before each measurement. 23 | * Default = 0 24 | */ 25 | void set_fcyc_clear_cache(int clear); 26 | 27 | /* 28 | * set_fcyc_cache_size - Set size of cache to use when clearing cache 29 | * Default = 1<<19 (512KB) 30 | */ 31 | void set_fcyc_cache_size(int bytes); 32 | 33 | /* 34 | * set_fcyc_cache_block - Set size of cache block 35 | * Default = 32 36 | */ 37 | void set_fcyc_cache_block(int bytes); 38 | 39 | /* 40 | * set_fcyc_compensate- When set, will attempt to compensate for 41 | * timer interrupt overhead 42 | * Default = 0 43 | */ 44 | void set_fcyc_compensate(int compensate_arg); 45 | 46 | /* 47 | * set_fcyc_k - Value of K in K-best measurement scheme 48 | * Default = 3 49 | */ 50 | void set_fcyc_k(int k); 51 | 52 | /* 53 | * set_fcyc_maxsamples - Maximum number of samples attempting to find 54 | * K-best within some tolerance. 55 | * When exceeded, just return best sample found. 56 | * Default = 20 57 | */ 58 | void set_fcyc_maxsamples(int maxsamples_arg); 59 | 60 | /* 61 | * set_fcyc_epsilon - Tolerance required for K-best 62 | * Default = 0.01 63 | */ 64 | void set_fcyc_epsilon(double epsilon_arg); 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /lab8-malloc/fsecs.c: -------------------------------------------------------------------------------- 1 | /**************************** 2 | * High-level timing wrappers 3 | ****************************/ 4 | #include 5 | #include "fsecs.h" 6 | #include "fcyc.h" 7 | #include "clock.h" 8 | #include "ftimer.h" 9 | #include "config.h" 10 | 11 | static double Mhz; /* estimated CPU clock frequency */ 12 | 13 | extern int verbose; /* -v option in mdriver.c */ 14 | 15 | /* 16 | * init_fsecs - initialize the timing package 17 | */ 18 | void init_fsecs(void) 19 | { 20 | Mhz = 0; /* keep gcc -Wall happy */ 21 | 22 | #if USE_FCYC 23 | if (verbose) 24 | printf("Measuring performance with a cycle counter.\n"); 25 | 26 | /* set key parameters for the fcyc package */ 27 | set_fcyc_maxsamples(20); 28 | set_fcyc_clear_cache(1); 29 | set_fcyc_compensate(1); 30 | set_fcyc_epsilon(0.01); 31 | set_fcyc_k(3); 32 | Mhz = mhz(verbose > 0); 33 | #elif USE_ITIMER 34 | if (verbose) 35 | printf("Measuring performance with the interval timer.\n"); 36 | #elif USE_GETTOD 37 | if (verbose) 38 | printf("Measuring performance with gettimeofday().\n"); 39 | #endif 40 | } 41 | 42 | /* 43 | * fsecs - Return the running time of a function f (in seconds) 44 | */ 45 | double fsecs(fsecs_test_funct f, void *argp) 46 | { 47 | #if USE_FCYC 48 | double cycles = fcyc(f, argp); 49 | return cycles/(Mhz*1e6); 50 | #elif USE_ITIMER 51 | return ftimer_itimer(f, argp, 10); 52 | #elif USE_GETTOD 53 | return ftimer_gettod(f, argp, 10); 54 | #endif 55 | } 56 | 57 | 58 | -------------------------------------------------------------------------------- /lab8-malloc/fsecs.h: -------------------------------------------------------------------------------- 1 | typedef void (*fsecs_test_funct)(void *); 2 | 3 | void init_fsecs(void); 4 | double fsecs(fsecs_test_funct f, void *argp); 5 | -------------------------------------------------------------------------------- /lab8-malloc/ftimer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Function timers 3 | */ 4 | typedef void (*ftimer_test_funct)(void *); 5 | 6 | /* Estimate the running time of f(argp) using the Unix interval timer. 7 | Return the average of n runs */ 8 | double ftimer_itimer(ftimer_test_funct f, void *argp, int n); 9 | 10 | 11 | /* Estimate the running time of f(argp) using gettimeofday 12 | Return the average of n runs */ 13 | double ftimer_gettod(ftimer_test_funct f, void *argp, int n); 14 | 15 | -------------------------------------------------------------------------------- /lab8-malloc/memlib.c: -------------------------------------------------------------------------------- 1 | /* 2 | * memlib.c - a module that simulates the memory system. Needed because it 3 | * allows us to interleave calls from the student's malloc package 4 | * with the system's malloc package in libc. 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include "memlib.h" 15 | #include "config.h" 16 | 17 | /* private variables */ 18 | static char *mem_start_brk; /* points to first byte of heap */ 19 | static char *mem_brk; /* points to last byte of heap */ 20 | static char *mem_max_addr; /* largest legal heap address */ 21 | 22 | /* 23 | * mem_init - initialize the memory system model 24 | */ 25 | void mem_init(void) 26 | { 27 | /* allocate the storage we will use to model the available VM */ 28 | if ((mem_start_brk = (char *)malloc(MAX_HEAP)) == NULL) { 29 | fprintf(stderr, "mem_init_vm: malloc error\n"); 30 | exit(1); 31 | } 32 | 33 | mem_max_addr = mem_start_brk + MAX_HEAP; /* max legal heap address */ 34 | mem_brk = mem_start_brk; /* heap is empty initially */ 35 | } 36 | 37 | /* 38 | * mem_deinit - free the storage used by the memory system model 39 | */ 40 | void mem_deinit(void) 41 | { 42 | free(mem_start_brk); 43 | } 44 | 45 | /* 46 | * mem_reset_brk - reset the simulated brk pointer to make an empty heap 47 | */ 48 | void mem_reset_brk() 49 | { 50 | mem_brk = mem_start_brk; 51 | } 52 | 53 | /* 54 | * mem_sbrk - simple model of the sbrk function. Extends the heap 55 | * by incr bytes and returns the start address of the new area. In 56 | * this model, the heap cannot be shrunk. 57 | */ 58 | void *mem_sbrk(int incr) 59 | { 60 | char *old_brk = mem_brk; 61 | 62 | if ( (incr < 0) || ((mem_brk + incr) > mem_max_addr)) { 63 | errno = ENOMEM; 64 | fprintf(stderr, "ERROR: mem_sbrk failed. Ran out of memory...\n"); 65 | return (void *)-1; 66 | } 67 | mem_brk += incr; 68 | return (void *)old_brk; 69 | } 70 | 71 | /* 72 | * mem_heap_lo - return address of the first heap byte 73 | */ 74 | void *mem_heap_lo() 75 | { 76 | return (void *)mem_start_brk; 77 | } 78 | 79 | /* 80 | * mem_heap_hi - return address of last heap byte 81 | */ 82 | void *mem_heap_hi() 83 | { 84 | return (void *)(mem_brk - 1); 85 | } 86 | 87 | /* 88 | * mem_heapsize() - returns the heap size in bytes 89 | */ 90 | size_t mem_heapsize() 91 | { 92 | return (size_t)(mem_brk - mem_start_brk); 93 | } 94 | 95 | /* 96 | * mem_pagesize() - returns the page size of the system 97 | */ 98 | size_t mem_pagesize() 99 | { 100 | return (size_t)getpagesize(); 101 | } 102 | -------------------------------------------------------------------------------- /lab8-malloc/memlib.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void mem_init(void); 4 | void mem_deinit(void); 5 | void *mem_sbrk(int incr); 6 | void mem_reset_brk(void); 7 | void *mem_heap_lo(void); 8 | void *mem_heap_hi(void); 9 | size_t mem_heapsize(void); 10 | size_t mem_pagesize(void); 11 | 12 | -------------------------------------------------------------------------------- /lab8-malloc/mm.c: -------------------------------------------------------------------------------- 1 | /* 2 | * mm-naive.c - The fastest, least memory-efficient malloc package. 3 | * 4 | * In this naive approach, a block is allocated by simply incrementing 5 | * the brk pointer. A block is pure payload. There are no headers or 6 | * footers. Blocks are never coalesced or reused. Realloc is 7 | * implemented directly using mm_malloc and mm_free. 8 | * 9 | * NOTE TO STUDENTS: Replace this header comment with your own header 10 | * comment that gives a high level description of your solution. 11 | */ 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include "mm.h" 19 | #include "memlib.h" 20 | 21 | /********************************************************* 22 | * NOTE TO STUDENTS: Before you do anything else, please 23 | * provide your team information in the following struct. 24 | ********************************************************/ 25 | team_t team = { 26 | /* Team name */ 27 | "ateam", 28 | /* First member's full name */ 29 | "Harry Bovik", 30 | /* First member's email address */ 31 | "bovik@cs.cmu.edu", 32 | /* Second member's full name (leave blank if none) */ 33 | "", 34 | /* Second member's email address (leave blank if none) */ 35 | "" 36 | }; 37 | 38 | /* single word (4) or double word (8) alignment */ 39 | #define ALIGNMENT 8 40 | 41 | /* rounds up to the nearest multiple of ALIGNMENT */ 42 | #define ALIGN(size) (((size) + (ALIGNMENT-1)) & ~0x7) 43 | 44 | 45 | #define SIZE_T_SIZE (ALIGN(sizeof(size_t))) 46 | 47 | /* 48 | * mm_init - initialize the malloc package. 49 | */ 50 | int mm_init(void) 51 | { 52 | return 0; 53 | } 54 | 55 | /* 56 | * mm_malloc - Allocate a block by incrementing the brk pointer. 57 | * Always allocate a block whose size is a multiple of the alignment. 58 | */ 59 | void *mm_malloc(size_t size) 60 | { 61 | int newsize = ALIGN(size + SIZE_T_SIZE); 62 | void *p = mem_sbrk(newsize); 63 | if (p == (void *)-1) 64 | return NULL; 65 | else { 66 | *(size_t *)p = size; 67 | return (void *)((char *)p + SIZE_T_SIZE); 68 | } 69 | } 70 | 71 | /* 72 | * mm_free - Freeing a block does nothing. 73 | */ 74 | void mm_free(void *ptr) 75 | { 76 | } 77 | 78 | /* 79 | * mm_realloc - Implemented simply in terms of mm_malloc and mm_free 80 | */ 81 | void *mm_realloc(void *ptr, size_t size) 82 | { 83 | void *oldptr = ptr; 84 | void *newptr; 85 | size_t copySize; 86 | 87 | newptr = mm_malloc(size); 88 | if (newptr == NULL) 89 | return NULL; 90 | copySize = *(size_t *)((char *)oldptr - SIZE_T_SIZE); 91 | if (size < copySize) 92 | copySize = size; 93 | memcpy(newptr, oldptr, copySize); 94 | mm_free(oldptr); 95 | return newptr; 96 | } 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /lab8-malloc/mm.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | extern int mm_init (void); 4 | extern void *mm_malloc (size_t size); 5 | extern void mm_free (void *ptr); 6 | extern void *mm_realloc(void *ptr, size_t size); 7 | 8 | 9 | /* 10 | * Students work in teams of one or two. Teams enter their team name, 11 | * personal names and login IDs in a struct of this 12 | * type in their bits.c file. 13 | */ 14 | typedef struct { 15 | char *teamname; /* ID1+ID2 or ID1 */ 16 | char *name1; /* full name of first member */ 17 | char *id1; /* login ID of first member */ 18 | char *name2; /* full name of second member (if any) */ 19 | char *id2; /* login ID of second member */ 20 | } team_t; 21 | 22 | extern team_t team; 23 | 24 | -------------------------------------------------------------------------------- /lab8-malloc/short1-bal.rep: -------------------------------------------------------------------------------- 1 | 20000 2 | 6 3 | 12 4 | 1 5 | a 0 2040 6 | a 1 2040 7 | f 1 8 | a 2 48 9 | a 3 4072 10 | f 3 11 | a 4 4072 12 | f 0 13 | f 2 14 | a 5 4072 15 | f 4 16 | f 5 17 | -------------------------------------------------------------------------------- /lab8-malloc/short2-bal.rep: -------------------------------------------------------------------------------- 1 | 20000 2 | 6 3 | 12 4 | 1 5 | a 0 2040 6 | a 1 4010 7 | a 2 48 8 | a 3 4072 9 | a 4 4072 10 | a 5 4072 11 | f 0 12 | f 1 13 | f 2 14 | f 3 15 | f 4 16 | f 5 17 | -------------------------------------------------------------------------------- /lab9-proxy/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Proxy Lab 2 | # 3 | # You may modify this file any way you like (except for the handin 4 | # rule). You instructor will type "make" on your specific Makefile to 5 | # build your proxy from sources. 6 | 7 | CC = gcc 8 | CFLAGS = -g -Wall 9 | LDFLAGS = -lpthread 10 | 11 | all: proxy 12 | 13 | csapp.o: csapp.c csapp.h 14 | $(CC) $(CFLAGS) -c csapp.c 15 | 16 | proxy.o: proxy.c csapp.h 17 | $(CC) $(CFLAGS) -c proxy.c 18 | 19 | proxy: proxy.o csapp.o 20 | $(CC) $(CFLAGS) proxy.o csapp.o -o proxy $(LDFLAGS) 21 | 22 | # Creates a tarball in ../proxylab-handin.tar that you can then 23 | # hand in. DO NOT MODIFY THIS! 24 | handin: 25 | (make clean; cd ..; tar cvf $(USER)-proxylab-handin.tar proxylab-handout --exclude tiny --exclude nop-server.py --exclude proxy --exclude driver.sh --exclude port-for-user.pl --exclude free-port.sh --exclude ".*") 26 | 27 | clean: 28 | rm -f *~ *.o proxy core *.tar *.zip *.gzip *.bzip *.gz 29 | 30 | -------------------------------------------------------------------------------- /lab9-proxy/README: -------------------------------------------------------------------------------- 1 | #################################################################### 2 | # CS:APP Proxy Lab 3 | # 4 | # Student Source Files 5 | #################################################################### 6 | 7 | This directory contains the files you will need for the CS:APP Proxy 8 | Lab. 9 | 10 | proxy.c 11 | csapp.h 12 | csapp.c 13 | These are starter files. csapp.c and csapp.h are described in 14 | your textbook. 15 | 16 | You may make any changes you like to these files. And you may 17 | create and handin any additional files you like. 18 | 19 | Please use `port-for-user.pl' or 'free-port.sh' to generate 20 | unique ports for your proxy or tiny server. 21 | 22 | Makefile 23 | This is the makefile that builds the proxy program. Type "make" 24 | to build your solution, or "make clean" followed by "make" for a 25 | fresh build. 26 | 27 | Type "make handin" to create the tarfile that you will be handing 28 | in. You can modify it any way you like. Your instructor will use your 29 | Makefile to build your proxy from source. 30 | 31 | port-for-user.pl 32 | Generates a random port for a particular user 33 | usage: ./port-for-user.pl 34 | 35 | free-port.sh 36 | Handy script that identifies an unused TCP port that you can use 37 | for your proxy or tiny. 38 | usage: ./free-port.sh 39 | 40 | driver.sh 41 | The autograder for Basic, Concurrency, and Cache. 42 | usage: ./driver.sh 43 | 44 | nop-server.py 45 | helper for the autograder. 46 | 47 | tiny 48 | Tiny Web server from the CS:APP text 49 | 50 | -------------------------------------------------------------------------------- /lab9-proxy/free-port.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 4 | # free-port.sh - returns an unused TCP port. 5 | # 6 | PORT_START=4500 7 | PORT_MAX=65000 8 | port=${PORT_START} 9 | 10 | while [ TRUE ] 11 | do 12 | portsinuse=`netstat --numeric-ports --numeric-hosts -a --protocol=tcpip | grep tcp | \ 13 | cut -c21- | cut -d':' -f2 | cut -d' ' -f1 | grep -E "[0-9]+" | uniq | tr "\n" " "` 14 | 15 | echo "${portsinuse}" | grep -wq "${port}" 16 | if [ "$?" == "0" ]; then 17 | if [ $port -eq ${PORT_MAX} ] 18 | then 19 | exit -1 20 | fi 21 | port=`expr ${port} + 1` 22 | else 23 | echo $port 24 | exit 0 25 | fi 26 | done 27 | -------------------------------------------------------------------------------- /lab9-proxy/nop-server.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # nop-server.py - This is a server that we use to create head-of-line 4 | # blocking for the concurrency test. It accepts a 5 | # connection, and then spins forever. 6 | # 7 | # usage: nop-server.py 8 | # 9 | import socket 10 | import sys 11 | 12 | #create an INET, STREAMing socket 13 | serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 14 | serversocket.bind(('', int(sys.argv[1]))) 15 | serversocket.listen(5) 16 | 17 | while 1: 18 | channel, details = serversocket.accept() 19 | while 1: 20 | continue 21 | -------------------------------------------------------------------------------- /lab9-proxy/port-for-user.pl: -------------------------------------------------------------------------------- 1 | #! /usr/bin/perl -w 2 | use strict; 3 | use Digest::MD5; 4 | # 5 | # port-for-user.pl - Return a port number, p, for a given user, with a 6 | # low probability of collisions. The port p is always even, so that 7 | # users can use p and p+1 for testing with proxy and the Tiny web 8 | # server. 9 | # 10 | # usage: ./port-for-user.pl [optional user name] 11 | # 12 | my $maxport = 65536; 13 | my $minport = 1024; 14 | 15 | 16 | # hashname - compute an even port number from a hash of the argument 17 | sub hashname { 18 | my $name = shift; 19 | my $port; 20 | my $hash = Digest::MD5::md5_hex($name); 21 | # take only the last 32 bits => last 8 hex digits 22 | $hash = substr($hash, -8); 23 | $hash = hex($hash); 24 | $port = $hash % ($maxport - $minport) + $minport; 25 | $port = $port & 0xfffffffe; 26 | print "$name: $port\n"; 27 | } 28 | 29 | 30 | # If called with no command line arg, then hash the userid, otherwise 31 | # hash the command line argument(s). 32 | if($#ARGV == -1) { 33 | my ($username) = getpwuid($<); 34 | hashname($username); 35 | } else { 36 | foreach(@ARGV) { 37 | hashname($_); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /lab9-proxy/proxy.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /* Recommended max cache and object sizes */ 4 | #define MAX_CACHE_SIZE 1049000 5 | #define MAX_OBJECT_SIZE 102400 6 | 7 | /* You won't lose style points for including this long line in your code */ 8 | static const char *user_agent_hdr = "User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:10.0.3) Gecko/20120305 Firefox/10.0.3\r\n"; 9 | 10 | int main() 11 | { 12 | printf("%s", user_agent_hdr); 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /lab9-proxy/tiny/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = -O2 -Wall -I . 3 | 4 | # This flag includes the Pthreads library on a Linux box. 5 | # Others systems will probably require something different. 6 | LIB = -lpthread 7 | 8 | all: tiny cgi 9 | 10 | tiny: tiny.c csapp.o 11 | $(CC) $(CFLAGS) -o tiny tiny.c csapp.o $(LIB) 12 | 13 | csapp.o: csapp.c 14 | $(CC) $(CFLAGS) -c csapp.c 15 | 16 | cgi: 17 | (cd cgi-bin; make) 18 | 19 | clean: 20 | rm -f *.o tiny *~ 21 | (cd cgi-bin; make clean) 22 | 23 | -------------------------------------------------------------------------------- /lab9-proxy/tiny/README: -------------------------------------------------------------------------------- 1 | Tiny Web server 2 | Dave O'Hallaron 3 | Carnegie Mellon University 4 | 5 | This is the home directory for the Tiny server, a 200-line Web 6 | server that we use in "15-213: Intro to Computer Systems" at Carnegie 7 | Mellon University. Tiny uses the GET method to serve static content 8 | (text, HTML, GIF, and JPG files) out of ./ and to serve dynamic 9 | content by running CGI programs out of ./cgi-bin. The default 10 | page is home.html (rather than index.html) so that we can view 11 | the contents of the directory from a browser. 12 | 13 | Tiny is neither secure nor complete, but it gives students an 14 | idea of how a real Web server works. Use for instructional purposes only. 15 | 16 | The code compiles and runs cleanly using gcc 2.95.3 17 | on a Linux 2.2.20 kernel. 18 | 19 | To install Tiny: 20 | Type "tar xvf tiny.tar" in a clean directory. 21 | 22 | To run Tiny: 23 | Run "tiny " on the server machine, 24 | e.g., "tiny 8000". 25 | Point your browser at Tiny: 26 | static content: http://:8000 27 | dynamic content: http://:8000/cgi-bin/adder?1&2 28 | 29 | Files: 30 | tiny.tar Archive of everything in this directory 31 | tiny.c The Tiny server 32 | Makefile Makefile for tiny.c 33 | home.html Test HTML page 34 | godzilla.gif Image embedded in home.html 35 | README This file 36 | cgi-bin/adder.c CGI program that adds two numbers 37 | cgi-bin/Makefile Makefile for adder.c 38 | 39 | -------------------------------------------------------------------------------- /lab9-proxy/tiny/cgi-bin/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = -O2 -Wall -I .. 3 | 4 | all: adder 5 | 6 | adder: adder.c 7 | $(CC) $(CFLAGS) -o adder adder.c 8 | 9 | clean: 10 | rm -f adder *~ 11 | -------------------------------------------------------------------------------- /lab9-proxy/tiny/cgi-bin/adder.c: -------------------------------------------------------------------------------- 1 | /* 2 | * adder.c - a minimal CGI program that adds two numbers together 3 | */ 4 | /* $begin adder */ 5 | #include "csapp.h" 6 | 7 | int main(void) { 8 | char *buf, *p; 9 | char arg1[MAXLINE], arg2[MAXLINE], content[MAXLINE]; 10 | int n1=0, n2=0; 11 | 12 | /* Extract the two arguments */ 13 | if ((buf = getenv("QUERY_STRING")) != NULL) { 14 | p = strchr(buf, '&'); 15 | *p = '\0'; 16 | strcpy(arg1, buf); 17 | strcpy(arg2, p+1); 18 | n1 = atoi(arg1); 19 | n2 = atoi(arg2); 20 | } 21 | 22 | /* Make the response body */ 23 | sprintf(content, "Welcome to add.com: "); 24 | sprintf(content, "%sTHE Internet addition portal.\r\n

", content); 25 | sprintf(content, "%sThe answer is: %d + %d = %d\r\n

", 26 | content, n1, n2, n1 + n2); 27 | sprintf(content, "%sThanks for visiting!\r\n", content); 28 | 29 | /* Generate the HTTP response */ 30 | printf("Connection: close\r\n"); 31 | printf("Content-length: %d\r\n", (int)strlen(content)); 32 | printf("Content-type: text/html\r\n\r\n"); 33 | printf("%s", content); 34 | fflush(stdout); 35 | 36 | exit(0); 37 | } 38 | /* $end adder */ 39 | -------------------------------------------------------------------------------- /lab9-proxy/tiny/godzilla.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YeXiaoRain/ICS_LAB_CMU_2016/dbef94921745c8c4429a64943dd982e7b6e4b34a/lab9-proxy/tiny/godzilla.gif -------------------------------------------------------------------------------- /lab9-proxy/tiny/godzilla.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YeXiaoRain/ICS_LAB_CMU_2016/dbef94921745c8c4429a64943dd982e7b6e4b34a/lab9-proxy/tiny/godzilla.jpg -------------------------------------------------------------------------------- /lab9-proxy/tiny/home.html: -------------------------------------------------------------------------------- 1 | 2 | test 3 | 4 | 5 | Dave O'Hallaron 6 | 7 | 8 | --------------------------------------------------------------------------------