| @@ -0,0 +1,4 @@ | |||
| -Xms512M | |||
| -Xmx4096M | |||
| -Xss32M | |||
| -XX:MaxMetaspaceSize=1024M | |||
| @@ -1,4 +1,4 @@ | |||
| * Exercise 1 | |||
| * Exercise description | |||
| The task in this exercise is to implement a 5-stage pipelined processor for | |||
| the [[./instructions.org][RISCV32I instruction set]]. | |||
| @@ -6,14 +6,27 @@ | |||
| at a time, whereas in exercise 2 your design will handle multiple instructions | |||
| at a time. | |||
| This is done by inserting 4 NOP instructions inbetween each source instruction, | |||
| enabling us to use the same tests for both exercise 1 and 2. | |||
| enabling us to use the same tests and harness for both exercise 1 and 2. | |||
| Once you are done with exercise 1, you can up the difficulty by setting nopPad | |||
| to false and start reading the [[exercise2.org][ex2 guide]]. | |||
| In the project skeleton files ([[./src/main/scala/][Found here]]) you can see that a lot of code has | |||
| already been provided. | |||
| already been provided, which can make it difficult to get started. | |||
| Hopefully this document can help clear up at least some of the confusion. | |||
| First an overview of what you are designing is presented, followed by a walk-through | |||
| for getting the most basic instructions to work. | |||
| In order to orient yourself you first need a map, thus a high level overview of the | |||
| processor you're going to design is showed underneath: | |||
| Keep in mind that this is just a high level sketch, omitting many details as well | |||
| entire features (for instance branch logic) | |||
| #+CAPTION: A very high level processor schematic. Registers, Instruction and data memory are already implemented. | |||
| [[./Images/FiveStage.png]] | |||
| Before going further it is useful to get an overview of what is provided out | |||
| of the box. | |||
| Now that you have an idea of what you're building it is time to take inventory of | |||
| the files included in the skeleton, and what, if anything should be added. | |||
| + [[./src/main/scala/Tile.scala]] | |||
| This is the top level module for the system as a whole. This is where the test | |||
| @@ -26,7 +39,11 @@ | |||
| should be declared and wired together. | |||
| Some of these modules have already been declared in order to wire up the | |||
| debugging logic for your test harness. | |||
| This file corresponds to the high-level overview in its entirety. | |||
| *This module is intended to be further fleshed out by you.* | |||
| As you work with this module, try keeping logic to a minimum to help readability. | |||
| If you end up with a lot of signal select logic, consider moving that to a separate | |||
| module. | |||
| + [[./src/main/scala/IF.scala]] | |||
| This is the instruction fetch stage. | |||
| @@ -94,10 +111,11 @@ | |||
| of these settings can be quite useful to alter. | |||
| The main attraction is the test options. By altering the verbosity settings you | |||
| may change what is output. | |||
| The settings are | |||
| The settings are: | |||
| + printIfSuccessful | |||
| Enables logging on tests that succeed | |||
| Enables logging on tests that succeed. | |||
| You typically want this turned off, at least for the full test runner. | |||
| + printErrors | |||
| Enables logging of errors. You obviously want this one on, at least on the single | |||
| @@ -147,6 +165,12 @@ | |||
| In your sketch you will eventually add a box for registers, IMEM and DMEM, which | |||
| should make it clear how the already finished modules fit into the grander design, | |||
| making the skeleton-code less mysterious. | |||
| To give you an idea of how a drill down looks like, here is my sketch of the ID stage: | |||
| #+CAPTION: Instruction decode stage, showing the various signals. | |||
| [[./Images/IDstage.png]] | |||
| I would generally advice to do these on paper, but don't half-ass them. | |||
| ** Adding numbers | |||
| @@ -174,11 +198,11 @@ | |||
| **** Step ¾: | |||
| In your console, type ~testOnly FiveStage.SingleTest~ to run only the tests that you | |||
| have defined in the [[./src/test/scala/Manifest.scala][test manifest]] (currently set to ~"forward2.s"~). | |||
| have defined in the [[./src/test/scala/Manifest.scala][test manifest]] (currently set to ~forward2.s~). | |||
| As you will first implement addition you should change this to the [[./src/test/resources/tests/basic/immediate/addi.s][add immediate test]]. | |||
| Luckily you do not have to deal with file paths, simply changing ~"forward2.s"~ to | |||
| ~"addi.s"~ suffices. | |||
| Luckily you do not have to deal with file paths, simply changing ~forward2.s~ to | |||
| ~addi.s~ suffices. | |||
| Ensure that the addi test is run by repeating the ~testOnly FiveStage.SingleTest~ | |||
| command. | |||
| @@ -188,7 +212,7 @@ | |||
| In [[./src/test/main/IF.scala]] you can see that the IMEM module is already set to fetch | |||
| the current program counter address (line 41), however since the current PC is stuck | |||
| at 0 it will fetch the same instruction over and over. Rectify this by commenting in | |||
| ~// PC := PC + 4.U~ at line 43. | |||
| ~// PC := PC + 4.U~ at line 48. | |||
| You can now verify that your design fetches new instructions each cycle by running | |||
| the test as in the previous step. | |||
| @@ -207,10 +231,10 @@ | |||
| Next you need to ensure that the registers and decoder gets the relevant data from the | |||
| instruction. | |||
| This is made more convenient by the fact that `Instruction` is a class, allowing you | |||
| This is made more convenient by the fact that ~Instruction~ is a class, allowing you | |||
| to access methods defined on it. | |||
| Keep in mind that it is only a class at compile and synthesis time, it will be | |||
| indistinguishable from a regular ~UIint(32.W)~ in your finished circuit. | |||
| Keep in mind that it is only a class during compile and build time, it will be | |||
| indistinguishable from a regular ~UInt(32.W)~ in your finished circuit. | |||
| The methods can be accessed like this: | |||
| #+BEGIN_SRC scala | |||
| // Drive funct6 of myModule with the 26th to 31st bit of instruction | |||
| @@ -221,9 +245,27 @@ | |||
| Your IF should now have an instruction as an OUTPUT, and your ID as an INPUT, however | |||
| they are not connected. This must be done in the CPU class where both the ID and IF are | |||
| instantiated. | |||
| In the overview sketch you probably noticed the barriers between IF and ID. | |||
| In accordance with the overview, it is incorrect to directly connect the two modules, | |||
| instead you must connect them using a *barrier*. | |||
| A barrier is responsible for keeping a value inbetween cycles, facilitating pipelining. | |||
| There is however one complicating matter: It takes a cycle to get the instruction from the | |||
| instruction memory, thus we don't want to delay it in the barrier! | |||
| In order to make code readable I suggest adding a new file for your barriers, containing | |||
| four different modules for the barriers your design will need. | |||
| Start with implementing your IF barrier module, which should contain the following: | |||
| + An input and output for PC where the output is delayed by a single cycle. | |||
| + An input and output for instruction where the output is wired directly to the input with | |||
| no delay. | |||
| The sketch for your barrier looks like this | |||
| #+CAPTION: The barrier between IF and ID. Note the passthrough for the instruction | |||
| [[./Images/IFID.png]] | |||
| **** Step 4½: | |||
| You should now verify that the correct control signals are produced. Using printf, ensure | |||
| You can now verify that the correct control signals are produced. Using printf, ensure | |||
| that: | |||
| + The program counter is increasing in increments of 4 | |||
| + The instruction in ID is as expected | |||
| @@ -231,7 +273,8 @@ | |||
| + The correct operands are fetched from the registers | |||
| Keep in mind that printf might not always be cycle accurate, the point is to ensure that | |||
| your processor design at least does something! | |||
| your processor design at least does something! In general it is better to use debug signals | |||
| and println, but for quick and dirty debugging printf is passable. | |||
| *** Step 5: | |||
| You will now have to create the EX stage. Use the structure of the IF and ID modules to | |||
| @@ -247,12 +290,24 @@ | |||
| ... | |||
| ) | |||
| io.aluResult := MuxLookup(0.U(32.W), io.aluOp, ALUopMap) | |||
| // MuxLookup API: https://github.com/freechipsproject/chisel3/wiki/Muxes-and-Input-Selection#muxlookup | |||
| io.aluResult := MuxLookup(io.aluOp, 0.U(32.W), ALUopMap) | |||
| #+END_SRC | |||
| As with the ID stage, you will need a barrier between ID and EX stage. | |||
| In this case, as the overview sketch indicates, all values should be delayed one cycle. | |||
| When you have finished the barrier, instantiate it and wire ID and EX together with the barrier in the | |||
| same fashion as IF and ID. | |||
| You don't need to add every single signal for your barrier, rather you should add them as they | |||
| become needed. | |||
| *** Step 6: | |||
| Your MEM stage does very little when an ADDI instruction is executed, so implementing it should | |||
| be easy. All you have to do is forward signals | |||
| be easy. All you have to do is forward signals. | |||
| From the overview sketch you can see that the same trick used in the IF/ID barrier is utilized | |||
| here, bypassing the data memory read value since it is already delayed by a cycle. | |||
| *** Step 7: | |||
| You now need to actually write the result back to your register bank. | |||
| @@ -0,0 +1,109 @@ | |||
| * Exercise 2 | |||
| Safety wheels are now officially off. | |||
| To verify this, set nopPadded to false in Manifest.scala and observe as all hell | |||
| breaks loose. | |||
| Let's break down what's going wrong and what we can do about it. | |||
| ** RAW Hazards | |||
| Consider the following program: | |||
| #+begin_src asm | |||
| main: | |||
| add x1, x1, x2 | |||
| add x1, x1, x1 | |||
| add x1, x1, x2 | |||
| #+end_src | |||
| In your implementation this will give you wrong results since the results | |||
| of the first add operation will not be available in the registers before | |||
| x1 is fetched for the second and third operation. | |||
| Your first task should therefore be to implement a forwarding unit | |||
| The forwarding unit is located in the EX stage and is responsible for selecting | |||
| the ALU input from three possible sources. | |||
| These sources are: | |||
| + The value received from the register bank | |||
| + The ALU result currently in MEM | |||
| + The writeback result | |||
| The forwarder prioritizes as follows: | |||
| + If the input register address is not the destination in either MEM or WB, select the | |||
| register. | |||
| + If the input register address is the destination register in WB, but not in MEM, select | |||
| the writeback signal. | |||
| + If the input register address is the destination register for the operation currently | |||
| in MEM, select that operation. | |||
| There is a special case you need take into account, namely load operations. | |||
| Considering the following program: | |||
| #+begin_src asm | |||
| main: | |||
| lw x1, 0(x2) | |||
| add x1, x1, x1 | |||
| add x1, x1, x1 | |||
| #+end_src | |||
| When the second operation (~add x1, x1, x1~) is in EX, the third clause in the forwarder | |||
| is triggered, however the result is not yet ready since fetching memory costs a cycle. | |||
| In order to fix this the forwarder must issue a signal that freezes the pipeline. | |||
| This is done by issuing a signal to the barrier registers, telling them to _not_ update | |||
| their contents, essentially repeating the last instruction. | |||
| There are many subtleties to consider here. | |||
| For instance: What should happen to the instruction currently | |||
| in MEM? If it too is repeated the hazard detector will trigger next cycle, effectively | |||
| deadlocking your processor. | |||
| What about when the write address and read address are similar in the ID stage? | |||
| Designing a forwarder can take very long, or it can be done very quickly, all depending | |||
| on how *methodical* you are. My advice is to design the algorithm first, then when you're | |||
| satisfied implement it on hardware. | |||
| ** Control hazards | |||
| Consider the following code | |||
| #+begin_src asm | |||
| main: | |||
| beq zero, zero, target | |||
| add x1, x1, x1 | |||
| add x1, x1, x1 | |||
| j main | |||
| target: | |||
| sub x1, x2, x2 | |||
| sub x2, x2, x2 | |||
| #+end_src | |||
| Depending on your design the two add instructions will be fetched before the beq jump happens. | |||
| Whenever a branch happens it is necessary to flush the spurious instructions that were fetched | |||
| before the branch was noticed. | |||
| However, simply waiting until the branch has been decided is not acceptable since that guarantees | |||
| lost cycles. | |||
| In your first iteration, simply assume branches will not be taken, and if they are taken issue | |||
| a warning to the barriers that hold spurious instructions telling them to render them impotent | |||
| by setting the control signals to do nothing. | |||
| * Putting the pedal to the metal | |||
| Once you have a design that RAW and control hazards you're ready to up the ante and add some | |||
| improvements to your design. | |||
| Some suggestions: | |||
| ** Branch predictor | |||
| Instead of assuming branch not taken, use a branch predictor. There are many different schemes, | |||
| but I advice you to stick to a simple one, such as 1-bit or 2-bit. | |||
| ** Fast branch handling | |||
| Certaing branches like BEQ and BNE can be calculated very quickly, wheras size comparison branches | |||
| (BGE, BLE and friends) take longer. It is therefore feasible to do these checks in the ID stage. | |||
| ** Adding a data cache | |||
| Unless you have already done the two suggested improvements, do not attempt to create a cache. | |||
| The first thing you need to do is to add a latency for memory fetching, if not you will have | |||
| nothing to improve upon. | |||
| If you still insist, start with the BTreeManyO3.s program and analyze the memory access pattern. | |||
| What sort of eviction policy and cache size would you choose for this pattern? | |||
| You should try writing additional benchmarking programs, it is important to have something measurable, | |||
| and the current programs are not made to test cache performance!! | |||
| @@ -2,6 +2,8 @@ | |||
| 4.2. Register-Register Arithmetic Instructions | |||
| -------------------------------------------------------------------------- | |||
| These do not render well on github, try using your text editor. | |||
| * ADD | |||
| - Summary : Addition with 3 GPRs, no overflow exception | |||
| @@ -8,13 +8,18 @@ class InstructionFetch extends MultiIOModule { | |||
| val testHarness = IO( | |||
| new Bundle { | |||
| val IMEMsetup = Input(new IMEMsetupSignals) | |||
| val PC = Output(UInt()) | |||
| val PC = Output(UInt()) | |||
| } | |||
| ) | |||
| /** | |||
| * TODO: Add signals for handling events such as jumps | |||
| * TODO: Add input signals for handling events such as jumps | |||
| * TODO: Add output signal for the instruction. | |||
| * The instruction is of type Bundle, which means that you must | |||
| * use the same syntax used in the testHarness for IMEM setup signals | |||
| * further up. | |||
| */ | |||
| val io = IO( | |||
| new Bundle { | |||
| @@ -35,7 +40,7 @@ class InstructionFetch extends MultiIOModule { | |||
| /** | |||
| * TODO: Your code here. | |||
| * | |||
| * | |||
| * You should expand on or rewrite the code below. | |||
| */ | |||
| IMEM.io.instructionAddress := PC | |||
| @@ -47,11 +52,10 @@ class InstructionFetch extends MultiIOModule { | |||
| /** | |||
| * Setup. You should not change this code | |||
| * Setup. You should not change this code. | |||
| */ | |||
| when(testHarness.IMEMsetup.setup) { | |||
| PC := 0.U | |||
| // TODO: You must set the instruction to Instruction.NOP here. | |||
| // throw new Exception("Just making sure you're seeing the line above") | |||
| io.instruction := Instruction.NOP | |||
| } | |||
| } | |||
| @@ -22,14 +22,17 @@ class Instruction extends Bundle(){ | |||
| def immediateJType = Cat(instruction(31), instruction(19, 12), instruction(20), instruction(30, 25), instruction(24, 21), 0.U(1.W)).asSInt | |||
| def immediateZType = instruction(19, 15).zext | |||
| def bubble(): Instruction = { | |||
| val bubbled = Wire(new Instruction) | |||
| bubbled.instruction := instruction | |||
| bubbled.instruction(6, 0) := BitPat.bitPatToUInt(BitPat("b0010011")) | |||
| bubbled | |||
| } | |||
| } | |||
| object Instruction { | |||
| def bubble(i: Instruction) = | |||
| i.opcode := BitPat.bitPatToUInt(BitPat("b0010011")) | |||
| def default: Instruction = { | |||
| def NOP: Instruction = { | |||
| val w = Wire(new Instruction) | |||
| w.instruction := 0.U | |||
| w.instruction := BitPat.bitPatToUInt(BitPat("b00000000000000000000000000010011")) | |||
| w | |||
| } | |||
| } | |||
| @@ -1,204 +1,204 @@ | |||
| main: | |||
| ori gp, gp, 0xFFFFFE09 | |||
| and gp, gp, ra | |||
| xor ra, ra, sp | |||
| sra ra, sp, sp | |||
| sltiu gp, ra, 0x01AE | |||
| srli sp, sp, 0x0005 | |||
| addi ra, sp, 0x0177 | |||
| srai sp, ra, 0x0003 | |||
| sub sp, ra, sp | |||
| slli sp, ra, 0x000B | |||
| add sp, gp, ra | |||
| slli gp, sp, 0x0006 | |||
| ori sp, ra, 0xFFFFFF64 | |||
| and gp, gp, gp | |||
| andi gp, gp, 0x0084 | |||
| xori ra, ra, 0xFFFFFEB4 | |||
| or sp, ra, ra | |||
| xori ra, sp, 0x003D | |||
| srli sp, sp, 0xFFFFFFF2 | |||
| addi ra, sp, 0x0012 | |||
| add ra, gp, sp | |||
| ori gp, ra, 0xFFFFFFB8 | |||
| sll ra, ra, ra | |||
| sll sp, gp, ra | |||
| slt ra, gp, ra | |||
| srai gp, gp, 0xFFFFFFFB | |||
| slli ra, ra, 0x0007 | |||
| sub sp, gp, sp | |||
| andi ra, gp, 0x002D | |||
| sub gp, gp, sp | |||
| srai ra, gp, 0x0005 | |||
| or sp, ra, sp | |||
| xori ra, gp, 0xFFFFFF54 | |||
| sll ra, sp, ra | |||
| sub gp, gp, sp | |||
| add ra, sp, sp | |||
| sll ra, gp, ra | |||
| add gp, sp, sp | |||
| ori gp, sp, 0xFFFFFE68 | |||
| srli sp, gp, 0xFFFFFFF1 | |||
| sltui ra, ra, 0xFFFFFE5D | |||
| srli ra, gp, 0x0006 | |||
| srai sp, sp, 0x0005 | |||
| andi sp, sp, 0x0129 | |||
| and sp, sp, sp | |||
| slli gp, ra, 0x0001 | |||
| or gp, gp, gp | |||
| or sp, gp, gp | |||
| slli gp, gp, 0x0006 | |||
| srl sp, ra, gp | |||
| sltui gp, ra, 0xFFFFFEC3 | |||
| add sp, gp, sp | |||
| xori ra, ra, 0xFFFFFFA2 | |||
| or gp, gp, sp | |||
| and sp, gp, gp | |||
| srai gp, sp, 0x0008 | |||
| add sp, sp, ra | |||
| slti sp, ra, 0xFFFFFFF7 | |||
| srli gp, ra, 0xFFFFFFFD | |||
| sll gp, ra, gp | |||
| sltu sp, sp, gp | |||
| srli gp, ra, 0x0002 | |||
| ori gp, sp, 0xFFFFFF28 | |||
| srl ra, gp, ra | |||
| slti gp, ra, 0x0054 | |||
| or gp, ra, ra | |||
| ori sp, gp, 0x01D9 | |||
| addi sp, ra, 0x0078 | |||
| sltiu sp, sp, 0xFFFFFF1E | |||
| srli gp, sp, 0x0000 | |||
| slti sp, ra, 0xFFFFFEF7 | |||
| srai ra, ra, 0x0001 | |||
| or sp, ra, gp | |||
| xor sp, sp, ra | |||
| sub sp, ra, sp | |||
| sub ra, gp, ra | |||
| sltiu gp, sp, 0xFFFFFE85 | |||
| addi sp, gp, 0x017C | |||
| sltiu ra, gp, 0xFFFFFF64 | |||
| xori sp, gp, 0x00A1 | |||
| xor ra, sp, gp | |||
| ori gp, ra, 0x00B6 | |||
| add ra, ra, sp | |||
| sltiu gp, ra, 0xFFFFFFEC | |||
| sltu gp, sp, ra | |||
| sll sp, ra, gp | |||
| add gp, ra, ra | |||
| or gp, ra, gp | |||
| xor sp, ra, sp | |||
| addi sp, gp, 0xFFFFFF4C | |||
| xor ra, sp, gp | |||
| xori ra, sp, 0xFFFFFF72 | |||
| xori gp, sp, 0xFFFFFE95 | |||
| or ra, ra, ra | |||
| slti ra, gp, 0xFFFFFE75 | |||
| slli sp, sp, 0x0004 | |||
| sltiu ra, ra, 0xFFFFFE25 | |||
| add sp, ra, gp | |||
| sltiu gp, gp, 0xFFFFFFDB | |||
| addi sp, sp, 0x003D | |||
| sll ra, ra, sp | |||
| ori ra, ra, 0x012C | |||
| add gp, ra, gp | |||
| xori sp, sp, 0x0157 | |||
| slti gp, sp, 0xFFFFFF2A | |||
| and sp, ra, ra | |||
| addi sp, gp, 0x0054 | |||
| slli gp, ra, 0xFFFFFFF2 | |||
| ori sp, sp, 0x0093 | |||
| add gp, gp, gp | |||
| and gp, gp, gp | |||
| sltui gp, ra, 0x00DE | |||
| slli sp, gp, 0x000D | |||
| slli sp, ra, 0xFFFFFFF5 | |||
| sltui sp, ra, 0xFFFFFF0E | |||
| and ra, gp, ra | |||
| add gp, sp, sp | |||
| slti ra, sp, 0x008C | |||
| srli ra, sp, 0x0000 | |||
| addi sp, sp, 0x0168 | |||
| slli ra, ra, 0xFFFFFFF3 | |||
| addi ra, gp, 0x012A | |||
| or sp, gp, ra | |||
| add ra, sp, gp | |||
| and gp, ra, ra | |||
| slli ra, gp, 0xFFFFFFF6 | |||
| or sp, gp, sp | |||
| or gp, ra, ra | |||
| ori gp, ra, 0x00EB | |||
| or sp, gp, ra | |||
| ori gp, sp, 0x01DA | |||
| andi ra, ra, 0xFFFFFFE9 | |||
| addi gp, sp, 0x00C9 | |||
| sltui ra, ra, 0xFFFFFF13 | |||
| sltui ra, ra, 0xFFFFFF3A | |||
| sltui sp, gp, 0xFFFFFE5A | |||
| ori sp, sp, 0xFFFFFFFE | |||
| and gp, sp, gp | |||
| sltui sp, ra, 0x0034 | |||
| srl gp, gp, ra | |||
| sll gp, sp, ra | |||
| ori ra, gp, 0xFFFFFEB6 | |||
| sll ra, sp, ra | |||
| sra ra, gp, sp | |||
| sub ra, sp, gp | |||
| xor gp, gp, sp | |||
| sub ra, ra, sp | |||
| srl gp, gp, sp | |||
| andi ra, ra, 0xFFFFFFCB | |||
| ori ra, ra, 0xFFFFFE1B | |||
| andi ra, ra, 0xFFFFFEC8 | |||
| sltui sp, gp, 0x0108 | |||
| add gp, ra, ra | |||
| sltiu ra, gp, 0xFFFFFE56 | |||
| sra gp, gp, ra | |||
| xori sp, gp, 0xFFFFFF0D | |||
| sub sp, gp, ra | |||
| slti ra, sp, 0x015D | |||
| slli sp, sp, 0x0004 | |||
| xor gp, sp, ra | |||
| srl ra, gp, ra | |||
| sltui ra, ra, 0xFFFFFF3C | |||
| add sp, sp, sp | |||
| add gp, gp, ra | |||
| andi sp, sp, 0xFFFFFF3A | |||
| srli ra, sp, 0x0004 | |||
| ori sp, gp, 0xFFFFFEAB | |||
| ori sp, ra, 0xFFFFFE95 | |||
| slli sp, sp, 0xFFFFFFF2 | |||
| xori gp, sp, 0x0040 | |||
| slti gp, sp, 0xFFFFFED1 | |||
| or sp, sp, sp | |||
| sltui sp, gp, 0x01B4 | |||
| addi ra, gp, 0x002D | |||
| and sp, gp, gp | |||
| or ra, ra, ra | |||
| or ra, gp, ra | |||
| or ra, gp, ra | |||
| sra ra, ra, gp | |||
| sra gp, ra, sp | |||
| sub ra, sp, ra | |||
| slti ra, ra, 0x0154 | |||
| slli ra, ra, 0x000A | |||
| ori ra, gp, 0xFFFFFEC2 | |||
| ori ra, sp, 0x0075 | |||
| addi gp, sp, 0x0079 | |||
| xor gp, ra, sp | |||
| srli ra, sp, 0x0008 | |||
| srai ra, ra, 0x000F | |||
| sltu sp, sp, ra | |||
| slli ra, gp, 0xFFFFFFF5 | |||
| slti gp, gp, 0x00E0 | |||
| addi gp, ra, 0xFFFFFF72 | |||
| srl ra, ra, gp | |||
| sltui gp, sp, 0xFFFFFEAA | |||
| xor sp, ra, gp | |||
| and gp, sp, ra | |||
| srli gp, gp, 0x0003 | |||
| xori ra, ra, 0x01BD | |||
| sub ra, gp, sp | |||
| slli gp, gp, 0x0006 | |||
| sra sp, gp, gp | |||
| add sp, sp, sp | |||
| srai ra, sp, 0x0001 | |||
| slli gp, ra, 0x0010 | |||
| andi ra, ra, 0xFFFFFFA8 | |||
| add sp, ra, sp | |||
| srai ra, gp, 0x000E | |||
| srai ra, sp, 0x0005 | |||
| addi ra, gp, 0xFFFFFF83 | |||
| xor gp, sp, ra | |||
| srai sp, gp, 0x0004 | |||
| srli ra, ra, 0x0007 | |||
| sll gp, ra, gp | |||
| xori ra, sp, 0x0065 | |||
| or ra, sp, ra | |||
| slt sp, gp, ra | |||
| addi ra, sp, 0xFFFFFE34 | |||
| slli gp, sp, 0x0007 | |||
| sll ra, sp, gp | |||
| sltui gp, gp, 0xFFFFFE62 | |||
| slti sp, sp, 0x0019 | |||
| xori ra, gp, 0x0092 | |||
| sltui gp, sp, 0xFFFFFF29 | |||
| srl sp, ra, gp | |||
| xori sp, gp, 0xFFFFFF4C | |||
| add sp, ra, gp | |||
| add sp, gp, ra | |||
| xori gp, gp, 0x0163 | |||
| add ra, gp, gp | |||
| srli gp, gp, 0x000B | |||
| add sp, ra, ra | |||
| sltu ra, ra, sp | |||
| sll sp, ra, ra | |||
| ori sp, sp, 0xFFFFFF6B | |||
| slli gp, gp, 0x0006 | |||
| xori sp, ra, 0x00A7 | |||
| add sp, ra, ra | |||
| add ra, gp, gp | |||
| addi gp, gp, 0xFFFFFFE9 | |||
| sra sp, ra, gp | |||
| add gp, ra, ra | |||
| ori gp, gp, 0x0002 | |||
| addi gp, gp, 0x002F | |||
| sll sp, sp, ra | |||
| srli sp, ra, 0x000E | |||
| ori gp, sp, 0x00EB | |||
| sra gp, ra, sp | |||
| sra sp, sp, gp | |||
| slli sp, ra, 0x0008 | |||
| srl sp, sp, sp | |||
| and gp, ra, ra | |||
| sra ra, ra, gp | |||
| add sp, gp, ra | |||
| andi sp, sp, 0x0039 | |||
| sll ra, gp, sp | |||
| andi gp, ra, 0xFFFFFECC | |||
| sll sp, sp, sp | |||
| sub sp, sp, ra | |||
| srai ra, sp, 0x0008 | |||
| xor gp, ra, sp | |||
| add sp, sp, sp | |||
| sub gp, ra, gp | |||
| xori gp, sp, 0x01EE | |||
| and ra, ra, ra | |||
| ori gp, ra, 0xFFFFFE96 | |||
| slli ra, gp, 0x0002 | |||
| srli gp, ra, 0x000D | |||
| add ra, sp, sp | |||
| andi sp, gp, 0xFFFFFEC0 | |||
| andi sp, gp, 0xFFFFFE7A | |||
| xori ra, sp, 0x0169 | |||
| xori gp, sp, 0xFFFFFE02 | |||
| andi ra, ra, 0xFFFFFFD1 | |||
| xor ra, sp, gp | |||
| xori gp, gp, 0x00AB | |||
| srl ra, ra, gp | |||
| and ra, ra, sp | |||
| xori gp, sp, 0x005D | |||
| srai sp, sp, 0x000A | |||
| addi ra, sp, 0xFFFFFE19 | |||
| srl gp, sp, gp | |||
| add ra, ra, sp | |||
| srai gp, ra, 0x000E | |||
| sltu gp, gp, sp | |||
| srli sp, ra, 0x0004 | |||
| ori gp, sp, 0xFFFFFE6E | |||
| and gp, ra, ra | |||
| ori gp, ra, 0xFFFFFFAF | |||
| srl ra, ra, ra | |||
| or sp, ra, ra | |||
| addi ra, gp, 0x0084 | |||
| ori sp, sp, 0xFFFFFF3D | |||
| xor gp, ra, gp | |||
| sra ra, ra, gp | |||
| xori ra, sp, 0x0040 | |||
| srai gp, gp, 0x0002 | |||
| xori ra, ra, 0xFFFFFE9A | |||
| sra ra, sp, sp | |||
| ori gp, sp, 0xFFFFFFB8 | |||
| sll sp, ra, ra | |||
| sll sp, ra, gp | |||
| sll gp, sp, sp | |||
| sra gp, ra, ra | |||
| srli gp, gp, 0x0001 | |||
| ori gp, sp, 0x0018 | |||
| and gp, gp, gp | |||
| sll gp, sp, gp | |||
| srli gp, sp, 0x0006 | |||
| add gp, ra, ra | |||
| add gp, ra, sp | |||
| sra sp, ra, ra | |||
| ori sp, ra, 0x0022 | |||
| and gp, gp, gp | |||
| add ra, sp, ra | |||
| sll sp, gp, gp | |||
| ori gp, sp, 0x008E | |||
| add sp, ra, sp | |||
| and sp, gp, gp | |||
| addi ra, sp, 0x0145 | |||
| and sp, gp, gp | |||
| sll gp, ra, sp | |||
| addi sp, sp, 0xFFFFFFAF | |||
| xori sp, ra, 0xFFFFFE2C | |||
| srl gp, ra, gp | |||
| sub ra, sp, gp | |||
| add sp, ra, ra | |||
| slli sp, sp, 0x0006 | |||
| sltu gp, sp, ra | |||
| sub gp, ra, sp | |||
| xori ra, ra, 0xFFFFFF9A | |||
| addi sp, sp, 0xFFFFFE12 | |||
| slli ra, ra, 0x0003 | |||
| slli gp, ra, 0x0004 | |||
| add gp, gp, gp | |||
| xori ra, ra, 0xFFFFFED7 | |||
| andi gp, gp, 0xFFFFFE05 | |||
| and gp, gp, sp | |||
| addi gp, gp, 0xFFFFFEE5 | |||
| slli ra, gp, 0x000A | |||
| sll sp, gp, gp | |||
| and ra, gp, sp | |||
| ori ra, gp, 0xFFFFFE22 | |||
| srl sp, sp, gp | |||
| srli ra, sp, 0x0005 | |||
| slli ra, ra, 0x0005 | |||
| srai ra, ra, 0x0007 | |||
| srli ra, gp, 0x000F | |||
| andi gp, gp, 0xFFFFFF96 | |||
| sra sp, gp, gp | |||
| srai gp, gp, 0x000F | |||
| sub sp, sp, gp | |||
| sltiu ra, ra, 0xFFFFFF41 | |||
| and sp, sp, sp | |||
| xor gp, sp, ra | |||
| srai gp, sp, 0x000A | |||
| xori gp, gp, 0x00D3 | |||
| or gp, sp, sp | |||
| sltu gp, ra, gp | |||
| slli ra, gp, 0x0002 | |||
| or sp, gp, ra | |||
| addi ra, ra, 0x002B | |||
| addi gp, ra, 0x0035 | |||
| slli sp, gp, 0x0008 | |||
| addi gp, sp, 0x015E | |||
| xor ra, gp, sp | |||
| or ra, gp, ra | |||
| sll ra, gp, ra | |||
| sll gp, gp, ra | |||
| srli gp, ra, 0x000C | |||
| slt sp, ra, sp | |||
| sltiu sp, sp, 0xFFFFFE1C | |||
| ori sp, ra, 0xFFFFFE83 | |||
| andi sp, sp, 0xFFFFFEFC | |||
| addi ra, ra, 0xFFFFFF85 | |||
| ori gp, ra, 0x0084 | |||
| sll gp, gp, ra | |||
| xori gp, sp, 0xFFFFFF6D | |||
| sll gp, sp, gp | |||
| sra ra, sp, ra | |||
| xor ra, gp, sp | |||
| srl ra, ra, sp | |||
| srl ra, ra, sp | |||
| andi gp, ra, 0xFFFFFE7B | |||
| srai ra, sp, 0x000F | |||
| sub sp, sp, ra | |||
| or sp, gp, gp | |||
| slt ra, ra, gp | |||
| or gp, gp, sp | |||
| srli ra, sp, 0x000B | |||
| andi ra, gp, 0xFFFFFFD4 | |||
| slli ra, gp, 0x0009 | |||
| done | |||
| #regset x1, 123 | |||
| #regset x2, -40 | |||
| @@ -1,205 +1,205 @@ | |||
| main: | |||
| sltui gp, ra, 0x01AE | |||
| srli sp, sp, 0xFFFFFFFB | |||
| addi ra, sp, 0x0177 | |||
| sub sp, ra, sp | |||
| slli sp, ra, 0x000B | |||
| add sp, gp, ra | |||
| slli gp, sp, 0x0006 | |||
| ori sp, ra, 0xFFFFFF64 | |||
| and gp, gp, gp | |||
| andi gp, gp, 0x0084 | |||
| xori ra, ra, 0xFFFFFEB4 | |||
| or sp, ra, ra | |||
| addi sp, ra, 0x0078 | |||
| srli gp, sp, 0x0000 | |||
| srl sp, gp, sp | |||
| andi ra, gp, 0xFFFFFFF4 | |||
| srai ra, ra, 0xFFFFFFFF | |||
| sltu gp, sp, gp | |||
| or sp, ra, gp | |||
| sub ra, gp, ra | |||
| addi sp, gp, 0x017C | |||
| sltui ra, gp, 0xFFFFFF64 | |||
| xori sp, gp, 0x00A1 | |||
| xor ra, sp, gp | |||
| ori gp, ra, 0x00B6 | |||
| add ra, ra, sp | |||
| sltui gp, ra, 0xFFFFFFEC | |||
| sltu gp, sp, ra | |||
| sll sp, ra, gp | |||
| add gp, ra, ra | |||
| or gp, ra, gp | |||
| xor sp, ra, sp | |||
| addi sp, gp, 0xFFFFFF4C | |||
| xor ra, sp, gp | |||
| xori ra, sp, 0xFFFFFF72 | |||
| xori gp, sp, 0xFFFFFE95 | |||
| or ra, ra, ra | |||
| slti ra, gp, 0xFFFFFE75 | |||
| slli sp, sp, 0xFFFFFFFC | |||
| sltui ra, ra, 0xFFFFFE25 | |||
| add sp, ra, gp | |||
| sltui gp, gp, 0xFFFFFFDB | |||
| addi sp, sp, 0x003D | |||
| sll ra, ra, sp | |||
| ori ra, ra, 0x012C | |||
| add gp, ra, gp | |||
| xori sp, sp, 0x0157 | |||
| slti gp, sp, 0xFFFFFF2A | |||
| and sp, ra, ra | |||
| add gp, ra, ra | |||
| sltui ra, gp, 0xFFFFFE56 | |||
| sra gp, gp, ra | |||
| xori sp, gp, 0xFFFFFF0D | |||
| sub sp, gp, ra | |||
| slti ra, ra, 0x0154 | |||
| slli ra, ra, 0x000A | |||
| ori ra, gp, 0xFFFFFEC2 | |||
| ori ra, sp, 0x0075 | |||
| addi gp, sp, 0x0079 | |||
| xor gp, ra, sp | |||
| srli ra, sp, 0xFFFFFFF8 | |||
| slli gp, gp, 0x0006 | |||
| sra sp, gp, gp | |||
| add sp, sp, sp | |||
| slli gp, ra, 0xFFFFFFF0 | |||
| add sp, ra, sp | |||
| srai ra, sp, 0x0005 | |||
| addi ra, gp, 0xFFFFFF83 | |||
| xor gp, sp, ra | |||
| srli ra, ra, 0x0007 | |||
| sll gp, ra, gp | |||
| xori gp, gp, 0x0163 | |||
| add ra, gp, gp | |||
| add sp, ra, ra | |||
| sltu ra, ra, sp | |||
| sll sp, ra, ra | |||
| ori sp, sp, 0xFFFFFF6B | |||
| slli gp, gp, 0xFFFFFFFA | |||
| xori sp, ra, 0x00A7 | |||
| add sp, ra, ra | |||
| add ra, gp, gp | |||
| addi gp, gp, 0xFFFFFFE9 | |||
| sra sp, ra, gp | |||
| add gp, ra, ra | |||
| ori gp, gp, 0x0002 | |||
| addi gp, gp, 0x002F | |||
| sll sp, sp, ra | |||
| srli sp, ra, 0xFFFFFFF2 | |||
| ori gp, sp, 0x00EB | |||
| sra gp, ra, sp | |||
| sra sp, sp, gp | |||
| and gp, ra, ra | |||
| sra ra, ra, gp | |||
| add sp, gp, ra | |||
| srl gp, sp, gp | |||
| add ra, ra, sp | |||
| srai gp, ra, 0xFFFFFFF2 | |||
| srli sp, ra, 0xFFFFFFFC | |||
| ori gp, sp, 0xFFFFFE6E | |||
| and gp, ra, ra | |||
| ori gp, ra, 0xFFFFFFAF | |||
| srl ra, ra, ra | |||
| or sp, ra, ra | |||
| ori gp, sp, 0x0018 | |||
| and gp, gp, gp | |||
| slti gp, ra, 0x00C6 | |||
| sll gp, sp, gp | |||
| srli gp, sp, 0xFFFFFFFA | |||
| add gp, ra, ra | |||
| add gp, ra, sp | |||
| sra sp, ra, ra | |||
| ori sp, ra, 0x0022 | |||
| and gp, gp, gp | |||
| add ra, sp, ra | |||
| sll sp, gp, gp | |||
| ori gp, sp, 0x008E | |||
| slti ra, gp, 0x00B5 | |||
| add sp, ra, sp | |||
| and sp, gp, gp | |||
| addi ra, sp, 0x0145 | |||
| and sp, gp, gp | |||
| sll gp, ra, sp | |||
| addi sp, sp, 0xFFFFFFAF | |||
| xori sp, ra, 0xFFFFFE2C | |||
| srl gp, ra, gp | |||
| sub ra, sp, gp | |||
| add sp, ra, ra | |||
| slli sp, sp, 0x0006 | |||
| sub gp, ra, sp | |||
| sltu sp, ra, gp | |||
| xori ra, ra, 0xFFFFFF9A | |||
| addi sp, sp, 0xFFFFFE12 | |||
| slli ra, ra, 0xFFFFFFFD | |||
| add gp, gp, gp | |||
| xori ra, ra, 0xFFFFFED7 | |||
| andi gp, gp, 0xFFFFFE05 | |||
| and gp, gp, sp | |||
| addi gp, gp, 0xFFFFFEE5 | |||
| slli ra, gp, 0xFFFFFFF6 | |||
| sll sp, gp, gp | |||
| and ra, gp, sp | |||
| ori ra, gp, 0xFFFFFE22 | |||
| srl sp, sp, gp | |||
| srli ra, sp, 0x0005 | |||
| slli ra, ra, 0xFFFFFFFB | |||
| srai ra, ra, 0xFFFFFFF9 | |||
| srli ra, gp, 0xFFFFFFF1 | |||
| andi gp, gp, 0xFFFFFF96 | |||
| sra sp, gp, gp | |||
| srai gp, gp, 0x000F | |||
| sub sp, sp, gp | |||
| sltui ra, ra, 0xFFFFFF41 | |||
| and sp, sp, sp | |||
| xor gp, sp, ra | |||
| srai gp, sp, 0xFFFFFFF6 | |||
| xori gp, gp, 0x00D3 | |||
| or gp, sp, sp | |||
| sltu gp, ra, gp | |||
| slli ra, gp, 0x0002 | |||
| or sp, gp, ra | |||
| addi ra, ra, 0x002B | |||
| addi gp, ra, 0x0035 | |||
| slli sp, gp, 0x0008 | |||
| addi gp, sp, 0x015E | |||
| xor ra, gp, sp | |||
| or ra, gp, ra | |||
| sll ra, gp, ra | |||
| sll gp, gp, ra | |||
| srli gp, ra, 0xFFFFFFF4 | |||
| slt sp, ra, sp | |||
| sltui sp, sp, 0xFFFFFE1C | |||
| ori sp, ra, 0xFFFFFE83 | |||
| andi sp, sp, 0xFFFFFEFC | |||
| addi ra, ra, 0xFFFFFF85 | |||
| ori gp, ra, 0x0084 | |||
| sll gp, gp, ra | |||
| xori gp, sp, 0xFFFFFF6D | |||
| sll gp, sp, gp | |||
| sra ra, sp, ra | |||
| xor ra, gp, sp | |||
| srl ra, ra, sp | |||
| srl ra, ra, sp | |||
| andi gp, ra, 0xFFFFFE7B | |||
| srai ra, sp, 0xFFFFFFF1 | |||
| sub sp, sp, ra | |||
| or sp, gp, gp | |||
| slt ra, ra, gp | |||
| or gp, gp, sp | |||
| srli ra, sp, 0xFFFFFFF5 | |||
| andi ra, gp, 0xFFFFFFD4 | |||
| sra sp, sp, sp | |||
| add sp, ra, sp | |||
| sub gp, ra, sp | |||
| xori ra, gp, 0x0131 | |||
| add sp, sp, ra | |||
| addi sp, gp, 0x0003 | |||
| sll ra, ra, ra | |||
| slli gp, ra, 0x000E | |||
| andi ra, gp, 0xFFFFFE88 | |||
| srai ra, gp, 0xFFFFFFFA | |||
| done | |||
| ori gp, gp, 0xFFFFFE09 | |||
| and gp, gp, ra | |||
| srli sp, ra, 0x0002 | |||
| xor ra, ra, sp | |||
| or sp, ra, ra | |||
| xori ra, sp, 0x003D | |||
| addi ra, sp, 0x0012 | |||
| add ra, gp, sp | |||
| ori gp, ra, 0xFFFFFFB8 | |||
| sll ra, ra, ra | |||
| sll sp, gp, ra | |||
| slt ra, gp, ra | |||
| srai gp, gp, 0x0005 | |||
| slli ra, ra, 0x0007 | |||
| sub sp, gp, sp | |||
| andi ra, gp, 0x002D | |||
| sub gp, gp, sp | |||
| srai ra, gp, 0x0005 | |||
| or sp, ra, sp | |||
| xori ra, gp, 0xFFFFFF54 | |||
| sll ra, sp, ra | |||
| sub gp, gp, sp | |||
| add ra, sp, sp | |||
| sll ra, gp, ra | |||
| add gp, sp, sp | |||
| ori gp, sp, 0xFFFFFE68 | |||
| srli sp, gp, 0x000F | |||
| sltiu ra, ra, 0xFFFFFE5D | |||
| srli ra, gp, 0x0006 | |||
| srai sp, sp, 0x0005 | |||
| andi sp, sp, 0x0129 | |||
| and sp, sp, sp | |||
| slli gp, ra, 0x0001 | |||
| or gp, gp, gp | |||
| or sp, gp, gp | |||
| slli gp, gp, 0x0006 | |||
| srl sp, ra, gp | |||
| sltiu gp, ra, 0xFFFFFEC3 | |||
| add sp, gp, sp | |||
| srli ra, sp, 0x0001 | |||
| xori ra, ra, 0xFFFFFFA2 | |||
| or gp, gp, sp | |||
| and sp, gp, gp | |||
| srai gp, sp, 0x0008 | |||
| add sp, sp, ra | |||
| slti sp, ra, 0xFFFFFFF7 | |||
| srli gp, ra, 0x0003 | |||
| sll gp, ra, gp | |||
| sltu sp, sp, gp | |||
| srli gp, ra, 0x0002 | |||
| ori gp, sp, 0xFFFFFF28 | |||
| srl ra, gp, ra | |||
| or gp, ra, ra | |||
| ori sp, gp, 0x01D9 | |||
| and sp, ra, ra | |||
| addi sp, gp, 0x0054 | |||
| slli gp, ra, 0x000E | |||
| ori sp, sp, 0x0093 | |||
| srai sp, ra, 0x000F | |||
| slti ra, gp, 0xFFFFFFCB | |||
| add gp, gp, gp | |||
| and gp, gp, gp | |||
| sltiu gp, ra, 0x00DE | |||
| slli sp, gp, 0x000D | |||
| slli sp, ra, 0x000B | |||
| sltiu sp, ra, 0xFFFFFF0E | |||
| and ra, gp, ra | |||
| add gp, sp, sp | |||
| slti ra, sp, 0x008C | |||
| srli ra, sp, 0x0000 | |||
| addi sp, sp, 0x0168 | |||
| slli ra, ra, 0x000D | |||
| addi ra, gp, 0x012A | |||
| or sp, gp, ra | |||
| add ra, sp, gp | |||
| and gp, ra, ra | |||
| slli ra, gp, 0x000A | |||
| or sp, gp, sp | |||
| or gp, ra, ra | |||
| srli ra, sp, 0x0002 | |||
| ori gp, ra, 0x00EB | |||
| or sp, gp, ra | |||
| ori gp, sp, 0x01DA | |||
| andi ra, ra, 0xFFFFFFE9 | |||
| addi gp, sp, 0x00C9 | |||
| sltiu ra, ra, 0xFFFFFF13 | |||
| sltiu ra, ra, 0xFFFFFF3A | |||
| sltiu sp, gp, 0xFFFFFE5A | |||
| ori sp, sp, 0xFFFFFFFE | |||
| and gp, sp, gp | |||
| sltiu sp, ra, 0x0034 | |||
| srl gp, gp, ra | |||
| sll gp, sp, ra | |||
| ori ra, gp, 0xFFFFFEB6 | |||
| sll ra, sp, ra | |||
| sra ra, gp, sp | |||
| sub ra, sp, gp | |||
| xor gp, gp, sp | |||
| sub ra, ra, sp | |||
| srl gp, gp, sp | |||
| andi ra, ra, 0xFFFFFFCB | |||
| ori ra, ra, 0xFFFFFE1B | |||
| andi ra, ra, 0xFFFFFEC8 | |||
| sltiu sp, gp, 0x0108 | |||
| sub sp, gp, ra | |||
| slti ra, sp, 0x015D | |||
| slli sp, sp, 0x0004 | |||
| xor gp, sp, ra | |||
| srl ra, gp, ra | |||
| sltiu ra, ra, 0xFFFFFF3C | |||
| add sp, sp, sp | |||
| add gp, gp, ra | |||
| slli gp, gp, 0x0001 | |||
| andi sp, sp, 0xFFFFFF3A | |||
| slt gp, sp, gp | |||
| srli ra, sp, 0x0004 | |||
| ori sp, gp, 0xFFFFFEAB | |||
| ori sp, ra, 0xFFFFFE95 | |||
| slli sp, sp, 0x000E | |||
| xori gp, sp, 0x0040 | |||
| slti gp, sp, 0xFFFFFED1 | |||
| or sp, sp, sp | |||
| sltiu sp, gp, 0x01B4 | |||
| addi ra, gp, 0x002D | |||
| and sp, gp, gp | |||
| or ra, ra, ra | |||
| or ra, gp, ra | |||
| srli ra, ra, 0x0004 | |||
| or ra, gp, ra | |||
| sra ra, ra, gp | |||
| slli ra, gp, 0x000B | |||
| slti gp, gp, 0x00E0 | |||
| addi gp, ra, 0xFFFFFF72 | |||
| sltiu gp, sp, 0xFFFFFEAA | |||
| xor sp, ra, gp | |||
| and gp, sp, ra | |||
| srli gp, gp, 0x0003 | |||
| xori ra, ra, 0x01BD | |||
| srl ra, ra, gp | |||
| srai ra, gp, 0x0006 | |||
| sub ra, gp, sp | |||
| sll gp, ra, gp | |||
| xori ra, sp, 0x0065 | |||
| and ra, gp, ra | |||
| or ra, sp, ra | |||
| slt sp, gp, ra | |||
| addi ra, sp, 0xFFFFFE34 | |||
| slli gp, sp, 0x0007 | |||
| sll ra, sp, gp | |||
| sltiu gp, gp, 0xFFFFFE62 | |||
| slti sp, sp, 0x0019 | |||
| xori ra, gp, 0x0092 | |||
| sltiu gp, sp, 0xFFFFFF29 | |||
| srl sp, ra, gp | |||
| xori sp, gp, 0xFFFFFF4C | |||
| add sp, ra, gp | |||
| add sp, gp, ra | |||
| sra sp, sp, gp | |||
| slli sp, ra, 0x0008 | |||
| srl sp, sp, sp | |||
| add sp, gp, ra | |||
| andi sp, sp, 0x0039 | |||
| sll ra, gp, sp | |||
| andi gp, ra, 0xFFFFFECC | |||
| sll sp, sp, sp | |||
| sub sp, sp, ra | |||
| srai ra, sp, 0x0008 | |||
| xor gp, ra, sp | |||
| add sp, sp, sp | |||
| sub gp, ra, gp | |||
| xori gp, sp, 0x01EE | |||
| and ra, ra, ra | |||
| ori gp, ra, 0xFFFFFE96 | |||
| slli ra, gp, 0x0002 | |||
| srli gp, ra, 0x000D | |||
| srli sp, gp, 0x0005 | |||
| add ra, sp, sp | |||
| andi sp, gp, 0xFFFFFEC0 | |||
| andi sp, gp, 0xFFFFFE7A | |||
| xori ra, sp, 0x0169 | |||
| xori gp, sp, 0xFFFFFE02 | |||
| andi ra, ra, 0xFFFFFFD1 | |||
| xor ra, sp, gp | |||
| xori gp, gp, 0x00AB | |||
| srl ra, ra, gp | |||
| and ra, ra, sp | |||
| xori gp, sp, 0x005D | |||
| srai sp, sp, 0x000A | |||
| addi ra, sp, 0xFFFFFE19 | |||
| or sp, ra, ra | |||
| addi ra, gp, 0x0084 | |||
| ori sp, sp, 0xFFFFFF3D | |||
| xor gp, ra, gp | |||
| sra ra, ra, gp | |||
| xori ra, sp, 0x0040 | |||
| srai gp, gp, 0x0002 | |||
| xori ra, ra, 0xFFFFFE9A | |||
| sra ra, sp, sp | |||
| ori gp, sp, 0xFFFFFFB8 | |||
| sll sp, ra, ra | |||
| done | |||
| #regset x1, 123 | |||
| #regset x2, -40 | |||
| #regset x3, 0xFFEE | |||
| @@ -158,12 +158,13 @@ object Data { | |||
| rightShifted | |||
| } | |||
| def splitLoHi(loBits: Int): (Int, Int) = { | |||
| val hiBits = 32 - loBits | |||
| val sep = 31 - loBits | |||
| val lo = i.field(31, loBits) | |||
| val hi = i.field(sep, hiBits) | |||
| (lo, hi) | |||
| def splitHiLo(hiBits: Int): (Int, Int) = { | |||
| val loBits = 32 - hiBits | |||
| val sep = 31 - hiBits | |||
| val hi = i.field(31, hiBits) | |||
| val lo = i.field(sep, loBits) | |||
| say(s"split lo hi for $i with $hiBits high bits and got low: $lo, high: $hi") | |||
| (hi, lo) | |||
| } | |||
| def log2: Int = math.ceil(math.log(i.toDouble)/math.log(2.0)).toInt | |||
| @@ -93,14 +93,17 @@ object Ops { | |||
| def or( rd: Int, rs1: Int, imm: Int) = ArithImm(Reg(rd), Reg(rs1), Imm(imm), OR) | |||
| def xor( rd: Int, rs1: Int, imm: Int) = ArithImm(Reg(rd), Reg(rs1), Imm(imm), XOR) | |||
| def and( rd: Int, rs1: Int, imm: Int) = ArithImm(Reg(rd), Reg(rs1), Imm(imm), AND) | |||
| def sll( rd: Int, rs1: Int, imm: Int) = ArithImm(Reg(rd), Reg(rs1), Imm(imm), SLL) | |||
| def srl( rd: Int, rs1: Int, imm: Int) = ArithImm(Reg(rd), Reg(rs1), Imm(imm), SRL) | |||
| def sra( rd: Int, rs1: Int, imm: Int) = ArithImm(Reg(rd), Reg(rs1), Imm(imm), SRA) | |||
| def slt( rd: Int, rs1: Int, imm: Int) = ArithImm(Reg(rd), Reg(rs1), Imm(imm), SLT) | |||
| def sltu(rd: Int, rs1: Int, imm: Int) = ArithImm(Reg(rd), Reg(rs1), Imm(imm), SLTU) | |||
| def nop = add(0, 0, 0) | |||
| } | |||
| case class ArithImmShift(rd: Reg, rs1: Reg, shamt: Imm, op: ArithOp) extends Op with IType | |||
| object ArithImmShift { | |||
| def sll( rd: Int, rs1: Int, imm: Int) = ArithImmShift(Reg(rd), Reg(rs1), Imm(imm), SLL) | |||
| def srl( rd: Int, rs1: Int, imm: Int) = ArithImmShift(Reg(rd), Reg(rs1), Imm(imm), SRL) | |||
| def sra( rd: Int, rs1: Int, imm: Int) = ArithImmShift(Reg(rd), Reg(rs1), Imm(imm), SRA) | |||
| } | |||
| case class LUI(rd: Reg, imm: Imm) extends Op with UType | |||
| case class AUIPC(rd: Reg, imm: Imm) extends Op with UType | |||
| @@ -84,12 +84,12 @@ object Parser { | |||
| stringWs("xori") ~> arithImm.mapN{ArithImm.xor}, | |||
| stringWs("andi") ~> arithImm.mapN{ArithImm.and}, | |||
| stringWs("slli") ~> arithImm.mapN{ArithImm.sll}, | |||
| stringWs("srli") ~> arithImm.mapN{ArithImm.srl}, | |||
| stringWs("srai") ~> arithImm.mapN{ArithImm.sra}, | |||
| stringWs("slli") ~> arithImm.mapN{ArithImmShift.sll}, | |||
| stringWs("srli") ~> arithImm.mapN{ArithImmShift.srl}, | |||
| stringWs("srai") ~> arithImm.mapN{ArithImmShift.sra}, | |||
| stringWs("slti") ~> arithImm.mapN{ArithImm.slt}, | |||
| stringWs("sltui") ~> arithImm.mapN{ArithImm.sltu}, | |||
| stringWs("sltiu") ~> arithImm.mapN{ArithImm.sltu}, | |||
| // pseudos | |||
| stringWs("not") ~> (reg <~ sep, reg, ok(-1)).mapN{ArithImm.xor}, | |||
| @@ -98,8 +98,11 @@ object Parser { | |||
| // seqz rd, rs1 => sltiu rd, rs1, 1 | |||
| stringWs("seqz") ~> (reg <~ sep, reg, ok(1)).mapN{ArithImm.sltu}, | |||
| stringWs("li") ~> (reg ~ sep ~ int).collect{ | |||
| case((a, b), c) if (c.nBitsS <= 12) => ArithImm.add(a, 0, c) | |||
| stringWs("li") ~> (reg ~ sep ~ (hex | int)).collect{ | |||
| case((a, b), c) if (c.nBitsS <= 12) => { | |||
| say(s"for c: $c, nBitsS was ${c.nBitsS}") | |||
| ArithImm.add(a, 0, c) | |||
| } | |||
| }, | |||
| @@ -122,16 +125,16 @@ object Parser { | |||
| //////////////////////////////////////////// | |||
| //// load/store | |||
| stringWs("sw") ~> (reg <~ sep, int <~ char('('), reg <~ char(')')).mapN{case (rs2, offset, rs1) => SW(rs2, rs1, offset)}, | |||
| stringWs("lw") ~> (reg <~ sep, int <~ char('('), reg <~ char(')')).mapN{case (rd, offset, rs1) => LW(rd, rs1, offset)}, | |||
| stringWs("sw") ~> (reg <~ sep, (hex | int) <~ char('('), reg <~ char(')')).mapN{case (rs2, offset, rs1) => SW(rs2, rs1, offset)}, | |||
| stringWs("lw") ~> (reg <~ sep, (hex | int) <~ char('('), reg <~ char(')')).mapN{case (rd, offset, rs1) => LW(rd, rs1, offset)}, | |||
| //////////////////////////////////////////// | |||
| //// others | |||
| stringWs("auipc") ~> (reg <~ sep, int).mapN{AUIPC.apply}, | |||
| stringWs("lui") ~> (reg <~ sep, int).mapN{LUI.apply}, | |||
| stringWs("auipc") ~> (reg <~ sep, (hex | int)).mapN{AUIPC.apply}, | |||
| stringWs("lui") ~> (reg <~ sep, (hex | int)).mapN{LUI.apply}, | |||
| many(whitespace) ~> string("nop") ~> ok(Arith.add(0, 0, 0)), | |||
| many(whitespace) ~> string("done") ~> ok(DONE), | |||
| @@ -140,19 +143,18 @@ object Parser { | |||
| ).map(_.widen[Op]).reduce(_|_) | |||
| // def getShiftsHalfWord(offset: Int): (Int, Int) = (offset % 4) match { | |||
| // case 0 => (16, 16) | |||
| // case 1 => ( | |||
| // } | |||
| val multipleInstructions: Parser[List[Op]] = List( | |||
| stringWs("li") ~> (reg <~ sep, int.map(_.splitLoHi(12))).mapN{ case(rd, (lo, hi)) => List( | |||
| // stringWs("li") ~> (reg <~ sep, (hex | int).map(_.splitLoHi(20))).mapN{ case(rd, (hi, lo)) => { | |||
| stringWs("li") ~> (reg <~ sep, (hex | int).map(_.splitHiLo(20))).mapN{ case(rd, (hi, lo)) => { | |||
| say("hello?") | |||
| List( | |||
| ArithImm.add(rd, rd, lo), | |||
| LUI(rd, hi), | |||
| ArithImm.add(rd, 0, lo) | |||
| )}.map(_.widen[Op]), | |||
| )}}.map(_.widen[Op]), | |||
| // NOTE: THESE ARE NOT PSEUDO-OPS IN RISV32I! | |||
| // NOTE: THESE ARE NOT PSEUDO-OPS IN RISC-V32I! | |||
| // NOTE: USES A SPECIAL REGISTER | |||
| // NOTE: PROBABLY BROKEN, NOT EXHAUSTIVELY TESTED!!! | |||
| stringWs("lh") ~> (reg <~ sep, int <~ char('('), reg <~ char(')')).mapN{ | |||
| case (rd, offset, rs1) if (offset % 4 == 3) => { | |||
| val placeHolder = if(rd == Reg("a0").value) Reg("a1").value else Reg("a0").value | |||
| @@ -160,16 +162,16 @@ object Parser { | |||
| SW(placeHolder, 0, 2048), | |||
| LW(placeHolder, rs1.value, (offset & 0xFFFFFF1C)), | |||
| LW(rd.value, rs1.value, (offset & 0xFFFFFF1C) + 4), | |||
| ArithImm.sra(placeHolder, placeHolder, 24), | |||
| ArithImm.sll(rd.value, rd.value, 24), | |||
| ArithImm.sra(rd.value, rd.value, 16), | |||
| ArithImmShift.sra(placeHolder, placeHolder, 24), | |||
| ArithImmShift.sll(rd.value, rd.value, 24), | |||
| ArithImmShift.sra(rd.value, rd.value, 16), | |||
| Arith.add(rd, rd, placeHolder), | |||
| LW(placeHolder, 0, 2048)).reverse | |||
| } | |||
| case (rd, offset, rs1) if (offset % 4 == 2) => { | |||
| List( | |||
| LW(rd, rs1, (offset & 0xFFFFFF1C)), | |||
| ArithImm.sra(rd, rd, 16) | |||
| ArithImmShift.sra(rd, rd, 16) | |||
| ).reverse | |||
| } | |||
| @@ -177,8 +179,8 @@ object Parser { | |||
| val leftShift = if((offset % 4) == 0) 16 else 8 | |||
| List( | |||
| LW(rd, rs1, (offset & 0xFFFFFF1C)), | |||
| ArithImm.sll(rd, rd, leftShift), | |||
| ArithImm.sra(rd, rd, 16), | |||
| ArithImmShift.sll(rd, rd, leftShift), | |||
| ArithImmShift.sra(rd, rd, 16), | |||
| ).reverse | |||
| } | |||
| }.map(_.widen[Op]), | |||
| @@ -23,16 +23,17 @@ case class VM( | |||
| def stepInstruction: Either[Finished, ExecutionTrace[VM]] = { | |||
| if (pc.value == 0xEB1CEB1C) Left(Success) | |||
| else getOp flatMap { | |||
| case op: Branch => executeBranch(op) | |||
| case op: Arith => executeArith(op) | |||
| case op: ArithImm => executeArithImm(op) | |||
| case op: AUIPC => executeAUIPC(op) | |||
| case op: LUI => executeLUI(op) | |||
| case op: JALR => executeJALR(op) | |||
| case op: JAL => executeJAL(op) | |||
| case op: LW => executeLW(op) | |||
| case op: SW => executeSW(op) | |||
| case DONE => Left(Success) | |||
| case op: Branch => executeBranch(op) | |||
| case op: Arith => executeArith(op) | |||
| case op: ArithImm => executeArithImm(op) | |||
| case op: ArithImmShift => executeArithImmShift(op) | |||
| case op: AUIPC => executeAUIPC(op) | |||
| case op: LUI => executeLUI(op) | |||
| case op: JALR => executeJALR(op) | |||
| case op: JAL => executeJAL(op) | |||
| case op: LW => executeLW(op) | |||
| case op: SW => executeSW(op) | |||
| case DONE => Left(Success) | |||
| } | |||
| } | |||
| @@ -75,6 +76,13 @@ case class VM( | |||
| } | |||
| private def executeArithImmShift(op: ArithImmShift) = { | |||
| val (regUpdate, nextRegs) = regs.arithImm(op.rd, op.rs1, op.shamt, op.op.run) | |||
| val nextVM = this.copy(regs = nextRegs) | |||
| Right(step(nextVM, regUpdate.toList:_*)) | |||
| } | |||
| private def executeLUI(op: LUI) = { | |||
| val (regUpdate, nextRegs) = regs + (op.rd -> (op.imm.value << 12)) | |||
| val nextVM = this.copy(regs = nextRegs) | |||
| @@ -125,12 +125,11 @@ object assembler { | |||
| } | |||
| /** | |||
| * Currently not used, thus we allow too larg shifts. | |||
| * Used by SRI, SRAI, SLLI | |||
| */ | |||
| def setShiftTypeImmediate(instruction: Int, immediate: Int): Int = { | |||
| def setShiftTypeImmediate(shamt: Int, addr: Addr): Int => InstructionFragment = { | |||
| val points = List((24, 5)) | |||
| val withField = applyImmediate(5, immediate, points)(instruction) | |||
| withField | |||
| applyImmediateU(shamt, points, addr) | |||
| } | |||
| def setOpCode(opcode: Int): Int => Int = setField(0, 7, opcode) | |||
| @@ -142,16 +141,17 @@ object assembler { | |||
| def setOpCode(op: Op): Int => Int = op match { | |||
| case x: Branch => setOpCode("1100011".binary) | |||
| case x: Arith => setOpCode("0110011".binary) | |||
| case x: ArithImm => setOpCode("0010011".binary) | |||
| case x: LW => setOpCode("0000011".binary) | |||
| case x: SW => setOpCode("0100011".binary) | |||
| case x: JALR => setOpCode("1100111".binary) | |||
| case x: JAL => setOpCode("1101111".binary) | |||
| case x: AUIPC => setOpCode("0110111".binary) | |||
| case x: LUI => setOpCode("0010111".binary) | |||
| case DONE => setOpCode("0010011".binary) // done is turned into a NOP in the assembler. | |||
| case x: Branch => setOpCode("1100011".binary) | |||
| case x: Arith => setOpCode("0110011".binary) | |||
| case x: ArithImm => setOpCode("0010011".binary) | |||
| case x: ArithImmShift => setOpCode("0010011".binary) | |||
| case x: LW => setOpCode("0000011".binary) | |||
| case x: SW => setOpCode("0100011".binary) | |||
| case x: JALR => setOpCode("1100111".binary) | |||
| case x: JAL => setOpCode("1101111".binary) | |||
| case x: AUIPC => setOpCode("0010111".binary) | |||
| case x: LUI => setOpCode("0110111".binary) | |||
| case DONE => setOpCode("0010011".binary) // done is turned into a NOP in the assembler. | |||
| } | |||
| def setComparisonFunct(cmp: Comparison): Int => Int = cmp match { | |||
| @@ -195,7 +195,6 @@ object assembler { | |||
| setRs1(op.rs1.value) | |||
| def assembleSType(op: SType): Int => Int = { | |||
| // say("stype") | |||
| instruction => | |||
| (setRs1(op.rs1.value) andThen | |||
| setRs2(op.rs2.value))(instruction) | |||
| @@ -214,16 +213,17 @@ object assembler { | |||
| def assembleImmediate(op: Op, addr: Addr, labelMap: Map[Label, Addr]): Int => Either[(String, Addr), Int] = op match { | |||
| case DONE => instruction => Right(instruction) | |||
| case op: Arith => instruction => Right(instruction) | |||
| case op: ArithImm => setItypeImmediate(op.imm.value, addr) | |||
| case op: Branch => setBranchDestination(labelMap, op, addr) | |||
| case op: JALR => instruction => labelMap.lift(op.dst).toRight(s"label ${op.dst} not found", addr).flatMap(addr => setItypeImmediate(addr.value, addr)(instruction)) | |||
| case op: AUIPC => setUtypeImmediate(op.imm.value, addr) | |||
| case op: LUI => setUtypeImmediate(op.imm.value, addr) | |||
| case op: LW => setItypeImmediate(op.offset.value, addr) | |||
| case op: SW => setStypeImmediate(op.offset.value, addr) | |||
| case op: JAL => instruction => { | |||
| case DONE => instruction => Right(instruction) | |||
| case op: Arith => instruction => Right(instruction) | |||
| case op: ArithImm => setItypeImmediate(op.imm.value, addr) | |||
| case op: ArithImmShift => setShiftTypeImmediate(op.shamt.value, addr) | |||
| case op: Branch => setBranchDestination(labelMap, op, addr) | |||
| case op: JALR => instruction => labelMap.lift(op.dst).toRight(s"label ${op.dst} not found", addr).flatMap(addr => setItypeImmediate(addr.value, addr)(instruction)) | |||
| case op: AUIPC => setUtypeImmediate(op.imm.value, addr) | |||
| case op: LUI => setUtypeImmediate(op.imm.value, addr) | |||
| case op: LW => setItypeImmediate(op.offset.value, addr) | |||
| case op: SW => setStypeImmediate(op.offset.value, addr) | |||
| case op: JAL => instruction => { | |||
| val addressDistance = labelMap | |||
| .lift(op.dst).toRight(s"label ${op.dst} not found", addr) | |||
| .map(absoluteAddr => absoluteAddr - addr) | |||
| @@ -246,14 +246,18 @@ object assembler { | |||
| val opcode = setOpCode(op) | |||
| val extras: Int => Int = (instruction: Int) => op match { | |||
| case op: Branch => setComparisonFunct(op.comp)(instruction) | |||
| case op: ArithImm => setArithFunct(op.op)(instruction) | |||
| case op: Arith => setArithFunct(op.op)(instruction) | |||
| case op: JALR => setFunct3("000".binary)(instruction) | |||
| case op: LW => setFunct3("010".binary)(instruction) | |||
| case op: SW => setFunct3("010".binary)(instruction) | |||
| case DONE => (setFunct3("000".binary) andThen setFunct7("0000000".binary))(instruction) | |||
| case _ => instruction | |||
| case op: Branch => setComparisonFunct(op.comp)(instruction) | |||
| case op: ArithImm => setArithFunct(op.op)(instruction) | |||
| case op: ArithImmShift => setArithFunct(op.op)(instruction) | |||
| case op: Arith => setArithFunct(op.op)(instruction) | |||
| case op: JALR => setFunct3("000".binary)(instruction) | |||
| case op: LW => setFunct3("010".binary)(instruction) | |||
| case op: SW => setFunct3("010".binary)(instruction) | |||
| case DONE => (setFunct3("000".binary) andThen setFunct7("0000000".binary))(instruction) | |||
| case op: AUIPC => instruction | |||
| case op: JAL => instruction | |||
| case op: LUI => instruction | |||
| } | |||
| val withOp = opcode(0) | |||
| @@ -1,178 +0,0 @@ | |||
| package FiveStage | |||
| import cats.data.Writer | |||
| import cats._ | |||
| import cats.data.{ Op => _ } | |||
| import cats.implicits._ | |||
| object DTree { | |||
| // opaques WHEN | |||
| type Feature = String | |||
| type Value = String | |||
| type Cls = String | |||
| case class TrainingData(values: Map[Feature, Value], cls: Cls) | |||
| type TestData = Map[Feature, Value] | |||
| // Base | |||
| // def predict(data: TestData): Cls = "Died" | |||
| // Gendered | |||
| def predictStatic(data: TestData): Cls = | |||
| if(data("gender") == "female") | |||
| "survived" | |||
| else "died" | |||
| sealed trait Tree | |||
| case class Node(feature: Feature, children: Map[Value, Tree]) extends Tree | |||
| case class Leaf(cls: Cls) extends Tree | |||
| val genderBased: Tree = Node( | |||
| "gender", Map( | |||
| "female" -> Leaf("survived"), | |||
| "male" -> Leaf("died"), | |||
| )) | |||
| def predict(data: TestData)(tree: Tree): Cls = | |||
| tree match { | |||
| case Leaf(cls) => cls | |||
| case Node(feature, children) => predict(data)(children(data(feature))) | |||
| } | |||
| val data = Map("gender" -> "female", "family size" -> "0", "ticket" -> "1") | |||
| predict(data)(genderBased) // true | |||
| def entropy(classes: List[Cls]): Double = { | |||
| val total = classes.size | |||
| classes.groupBy(identity) | |||
| .mapValues { group => | |||
| val prop = group.size / total | |||
| prop * math.log(1.0 / prop) | |||
| }.values.sum | |||
| } | |||
| def bucketedEntropy(data: List[TrainingData], feature: Feature): Double = { | |||
| val total = data.size | |||
| val bucketed = data.groupBy(_.values(feature)) | |||
| .mapValues(_.map(_.cls)) | |||
| .toMap | |||
| bucketed.values.map { classes => | |||
| val prop = classes.size / total | |||
| prop * entropy(classes) | |||
| }.sum | |||
| } | |||
| def best(data: List[TrainingData], features: Set[Feature]): Feature = features.minBy(bucketedEntropy(data, _)) | |||
| def mostCommonCls(data: List[TrainingData]): Cls = ??? | |||
| def build(data: List[TrainingData], features: Set[Feature]): Tree = { | |||
| if(features.nonEmpty) { | |||
| val feature = best(data, features) | |||
| val buckets = data.groupBy(_.values(feature)) | |||
| Node(feature, buckets.mapValues(build(_, features - feature))) | |||
| } else { | |||
| Leaf(mostCommonCls(data)) | |||
| } | |||
| } | |||
| def withHKT { | |||
| sealed trait Tree[A] | |||
| case class Node[A](feature: Feature, children: Map[Value, A]) extends Tree[A] | |||
| case class Leaf[A](cls: Cls) extends Tree[A] | |||
| // import matryoshka._ | |||
| // import matryoshka.data.Fix | |||
| // import matryoshka.implicits._ | |||
| case class Fix[F[_]](unfix: F[Fix[F]]) | |||
| case class Cofree[F[_], A](head: A, tail: F[Cofree[F, A]]){ | |||
| def counit: A = head | |||
| def map[B](f: A => B)(implicit ev: Functor[F]): Cofree[F, B] = Cofree(f(head), tail.map(_.map(f))) | |||
| /** | |||
| * Coflatmap alters the value of the node based on its context, then recursively | |||
| * alters its tail independently (which makes sense as it's the only thing Cofree[F, A] => B can do. | |||
| */ | |||
| def coflatMap[B](fa: Cofree[F, A] => B)(implicit ev: Functor[F]): Cofree[F, B] = { | |||
| val b = fa(this) | |||
| val fb = tail.map(_.coflatMap(fa)) | |||
| Cofree(b, fb) | |||
| } | |||
| } | |||
| implicit val treeFunctor: Functor[Tree] = new Functor[Tree] { | |||
| def map[A, B](fa: Tree[A])(f: A => B): Tree[B] = fa match { | |||
| case Node(name, children) => Node(name, children.mapValues(f)) | |||
| case Leaf(cls) => Leaf(cls) | |||
| } | |||
| } | |||
| val genderBased: Fix[Tree] = | |||
| Fix(Node( | |||
| "gender", | |||
| Map( | |||
| "female" -> Fix(Leaf[Fix[Tree]]("survived")), | |||
| "male" -> Fix(Leaf[Fix[Tree]]("died")) | |||
| ))) | |||
| def build: ((List[TrainingData], Set[Feature])) => Tree[(List[TrainingData], Set[Feature])] = { | |||
| case (data, features) => | |||
| if(features.nonEmpty) { | |||
| val feature = best(data, features) | |||
| val buckets = data.groupBy(_.values(feature)) | |||
| val next = buckets.mapValues { subset => (subset, features - feature) } | |||
| Node(feature, next) | |||
| } else { | |||
| Leaf(mostCommonCls(data)) | |||
| } | |||
| } | |||
| def explore(testData: TestData): Fix[Tree] => Cls Either Fix[Tree] = | |||
| fix => fix.unfix match { | |||
| case Leaf(cls) => Left(cls) | |||
| case Node(feature, children) => Right(children.get(testData(feature)).get) | |||
| } | |||
| // Anamorphism: Generalized unfold, builds structures | |||
| def ana[F[_]: Functor, A](f: A => F[A])(a: A): Fix[F] = | |||
| Fix( (f(a)).map(ana(f)) ) | |||
| // Catamorphism: Generalized fold, tears structures down. | |||
| def cata[F[_]: Functor, A](fa: F[A] => A)(f: Fix[F]): A = { | |||
| fa(f.unfix.map(cata(fa))) | |||
| } | |||
| // def hyloSimple[F[_] : Functor, A, B](f: F[B] => B)(g: A => F[A]): A => B | |||
| def hyloSimple[F[_]: Functor, A, B](f: F[B] => B)(g: A => F[A])(a: A): B = | |||
| cata(f)(ana(g)(a)) | |||
| // A more powerful cata | |||
| def para[F[_]: Functor, A](f: F[(Fix[F], A)] => A)(fa: Fix[F]): A = | |||
| f(fa.unfix.map(x => (x, para(f)(x)))) | |||
| // A more powerful ana | |||
| def apo[F[_]: Functor, A](f: A => F[Either[Fix[F], A]])(a: A): Fix[F] = { | |||
| Fix(f(a).map{ | |||
| case Right(a) => apo(f)(a) | |||
| case Left(fix) => fix | |||
| }) | |||
| } | |||
| // When we have cofree | |||
| def histo[F[_]: Functor, A](f: F[Cofree[F, A]] => A)(fix: Fix[F]): A = { | |||
| def toCofree(fix: Fix[F]): Cofree[F, A] = | |||
| Cofree(histo(f)(fix), fix.unfix.map(toCofree)) | |||
| f(fix.unfix.map(toCofree)) | |||
| } | |||
| } | |||
| } | |||
| @@ -1,164 +0,0 @@ | |||
| package FiveStage | |||
| import cats.data.Writer | |||
| import cats._ | |||
| import cats.data.{ Op => _ } | |||
| import cats.implicits._ | |||
| import fileUtils.say | |||
| object DeletDis { | |||
| def delet = { | |||
| case class Fix[F[_]](unfix: F[Fix[F]]) | |||
| case class Cofree[F[_], A](head: A, tail: F[Cofree[F, A]]){ | |||
| def counit: A = head | |||
| def map[B](f: A => B)(implicit ev: Functor[F]): Cofree[F, B] = Cofree(f(head), tail.map(_.map(f))) | |||
| /** | |||
| * Coflatmap alters the value of the node based on its context, then recursively | |||
| * alters its tail independently (which makes sense as it's the only thing Cofree[F, A] => B can do. | |||
| */ | |||
| def coflatMap[B](fa: Cofree[F, A] => B)(implicit ev: Functor[F]): Cofree[F, B] = { | |||
| val b = fa(this) | |||
| val fb = tail.map(_.coflatMap(fa)) | |||
| Cofree(b, fb) | |||
| } | |||
| } | |||
| // Anamorphism: Generalized unfold, builds structures | |||
| def ana[F[_]: Functor, A](f: A => F[A])(a: A): Fix[F] = | |||
| Fix( (f(a)).map(ana(f)) ) | |||
| // Catamorphism: Generalized fold, tears structures down. | |||
| def cata[F[_]: Functor, A](fa: F[A] => A)(f: Fix[F]): A = { | |||
| fa(f.unfix.map(cata(fa))) | |||
| } | |||
| // def hyloSimple[F[_] : Functor, A, B](f: F[B] => B)(g: A => F[A]): A => B | |||
| def hylo[F[_]: Functor, A, B](f: F[B] => B)(g: A => F[A])(a: A): B = | |||
| cata(f)(ana(g)(a)) | |||
| // A more powerful cata | |||
| def para[F[_]: Functor, A](f: F[(Fix[F], A)] => A)(fa: Fix[F]): A = | |||
| f(fa.unfix.map(x => (x, para(f)(x)))) | |||
| // A more powerful ana | |||
| def apo[F[_]: Functor, A](f: A => F[Either[Fix[F], A]])(a: A): Fix[F] = { | |||
| Fix(f(a).map{ | |||
| case Right(a) => apo(f)(a) | |||
| case Left(fix) => fix | |||
| }) | |||
| } | |||
| // When we have cofree | |||
| def histo[F[_]: Functor, A](f: F[Cofree[F, A]] => A)(fix: Fix[F]): A = { | |||
| def toCofree(fix: Fix[F]): Cofree[F, A] = | |||
| Cofree(histo(f)(fix), fix.unfix.map(toCofree)) | |||
| f(fix.unfix.map(toCofree)) | |||
| } | |||
| sealed trait StackR | |||
| final case class DoneR(result: Int = 1) extends StackR | |||
| final case class MoreR(stack: StackR, next: Int) extends StackR | |||
| def unfoldStackR(n: Int): StackR = | |||
| if(n > 0) MoreR(unfoldStackR(n-1), n) else DoneR() | |||
| say(unfoldStackR(5)) | |||
| sealed trait Stack[A] | |||
| final case class Done[A](result: Int) extends Stack[A] | |||
| final case class More[A](a: A, next: Int) extends Stack[A] | |||
| object Stack { | |||
| implicit val stackFunctor: Functor[Stack] = new Functor[Stack] { | |||
| def map[A, B](fa: Stack[A])(f: A => B): Stack[B] = fa match { | |||
| case Done(result) => Done(result) | |||
| case More(a, next) => More(f(a), next) | |||
| } | |||
| } | |||
| def done[A](result: Int = 1): Stack[A] = Done(result) | |||
| def more[A](a: A, next: Int): Stack[A] = More(a, next) | |||
| } | |||
| import Stack._ | |||
| val stackCoalgebra: Int => Stack[Int] = | |||
| n => if(n > 0) more(n - 1, n) else done() | |||
| say(ana(stackCoalgebra)(5)) | |||
| val stackAlgebra: Stack[Int] => Int = { | |||
| case Done(result) => result | |||
| case More(acc, next) => acc * next | |||
| } | |||
| say(cata(stackAlgebra)(ana(stackCoalgebra)(5))) | |||
| say(hylo(stackAlgebra)(stackCoalgebra)(5)) | |||
| sealed trait Nat[A] | |||
| final case class Zero[A]() extends Nat[A] | |||
| final case class Succ[A](prev: A) extends Nat[A] | |||
| object Nat { | |||
| implicit val natFunctor: Functor[Nat] = new Functor[Nat] { | |||
| override def map[A, B](na: Nat[A])(f: A => B): Nat[B] = | |||
| na match { | |||
| case Zero() => Zero() | |||
| case Succ(a) => Succ(f(a)) | |||
| } | |||
| } | |||
| } | |||
| val natAlgebra: Nat[Int] => Int = { | |||
| case Zero() => 1 | |||
| case Succ(n) => { | |||
| say(s"nat alg succ $n") | |||
| n + 1 | |||
| } | |||
| } | |||
| val natAlgebraS: Nat[String] => String = { | |||
| case Zero() => "N" | |||
| case Succ(n) => n match { | |||
| case "N" => "NI" | |||
| case "NI" => "NIG" | |||
| case "NIG" => "NIGG" | |||
| case "NIGG" => "NIGGE" | |||
| case "NIGGE" => "NIGGER :-" | |||
| case s => s + "D" | |||
| } | |||
| } | |||
| val natCoalgebra: Int => Nat[Int] = | |||
| n => if (n == 0) Zero() else Succ(n - 1) | |||
| val b = ana(natCoalgebra)(9) | |||
| val c = cata(natAlgebraS)(b) | |||
| say(c) | |||
| val natAlgebraPara: Nat[(Fix[Nat], Int)] => Int = { | |||
| case Zero() => 1 | |||
| case Succ((fix, acc)) => { | |||
| say(s"nat para alg succ $fix, $acc") | |||
| cata(natAlgebra)(fix) * acc | |||
| } | |||
| } | |||
| val build = ana(natCoalgebra)(_) | |||
| say("built") | |||
| val tear = para(natAlgebraPara)(_) | |||
| say(tear(build(5))) | |||
| // say(ana(natCoalgebra)(5)) | |||
| val lastThreeSteps: Fix[Stack] = Fix(More(Fix(More(Fix(More(Fix(Done(1)),1)),2)),3)) | |||
| val stackCoalgebraApo: Int => Stack[Either[Fix[Stack], Int]] = | |||
| n => if(n > 3) more(n - 1, n).map(_.asRight) else lastThreeSteps.unfix.map(_.asLeft) | |||
| } | |||
| } | |||
| @@ -81,16 +81,17 @@ object PrintUtils { | |||
| val UNKNOWN = "UNKNOWN" | |||
| def printInstruction(op: Ops.Op, labelMap: Map[Label, Addr]): fansi.Str = op match { | |||
| case op: Branch => fansi.Color.Red(s"B${op.comp}\t${op.rs1.show}, ${op.rs2.show}, ${op.dst.show}\t[${labelMap.lift(op.dst).getOrElse(UNKNOWN)}]") | |||
| case op: Arith => s"${op.op}\t${op.rd.show}, ${op.rs1.show}, ${op.rs2.show}" | |||
| case op: ArithImm => s"${op.op}I\t${op.rd.show}, ${op.rs1.show}, ${op.imm.show}" | |||
| case op: JALR => fansi.Color.Green(s"JALR\t${op.rd.show}, ${op.rs1.show}, ${op.dst.show}\t[${labelMap.lift(op.dst).getOrElse(UNKNOWN)}]") | |||
| case op: JAL => fansi.Color.Magenta(s"JAL\t${op.rd.show}, ${op.dst.show} [${labelMap.lift(op.dst).getOrElse(UNKNOWN)}]") | |||
| case op: LW => s"LW\t${op.rd.show}, ${op.offset.show}(${op.rs1.show})" | |||
| case op: SW => s"SW\t${op.rs2.show}, ${op.offset.show}(${op.rs1.show})" | |||
| case op: LUI => s"LUI\t${op.rd.show}, ${op.imm.show}" | |||
| case op: AUIPC => s"AUIPC\t${op.rd.show}, ${op.imm.show}" | |||
| case DONE => s"DONE" | |||
| case op: Branch => fansi.Color.Red(s"B${op.comp}\t${op.rs1.show}, ${op.rs2.show}, ${op.dst.show}\t[${labelMap.lift(op.dst).getOrElse(UNKNOWN)}]") | |||
| case op: Arith => s"${op.op}\t${op.rd.show}, ${op.rs1.show}, ${op.rs2.show}" | |||
| case op: ArithImm => s"${op.op}I\t${op.rd.show}, ${op.rs1.show}, ${op.imm.show}" | |||
| case op: ArithImmShift => s"${op.op}I\t${op.rd.show}, ${op.rs1.show}, ${op.shamt.show}" | |||
| case op: JALR => fansi.Color.Green(s"JALR\t${op.rd.show}, ${op.rs1.show}, ${op.dst.show}\t[${labelMap.lift(op.dst).getOrElse(UNKNOWN)}]") | |||
| case op: JAL => fansi.Color.Magenta(s"JAL\t${op.rd.show}, ${op.dst.show} [${labelMap.lift(op.dst).getOrElse(UNKNOWN)}]") | |||
| case op: LW => s"LW\t${op.rd.show}, ${op.offset.show}(${op.rs1.show})" | |||
| case op: SW => s"SW\t${op.rs2.show}, ${op.offset.show}(${op.rs1.show})" | |||
| case op: LUI => s"LUI\t${op.rd.show}, ${op.imm.show}" | |||
| case op: AUIPC => s"AUIPC\t${op.rd.show}, ${op.imm.show}" | |||
| case DONE => s"DONE" | |||
| } | |||
| @@ -118,7 +119,7 @@ object PrintUtils { | |||
| def printBinary(bin: Map[Addr, Int]): String = { | |||
| bin.toList.sortBy(_._1.value).map{ case(addr, op) => s"$addr: ${op.hs}" }.mkString("\n","\n","\n") | |||
| bin.toList.sortBy(_._1.value).map{ case(addr, op) => s"$addr: ${op.hs}\t--\t${op.binary}" }.mkString("\n","\n","\n") | |||
| } | |||
| @@ -346,7 +347,8 @@ object PrintUtils { | |||
| def printLogSideBySide(trace: List[ExecutionTraceEvent], chiselTrace: List[CircuitTrace], program: Program): String = { | |||
| import LogParser._ | |||
| val header = "ADDRESS -- VM UPDATES --- DEVICE UNDER TEST UPDATES --- CORRESPONDING SOURCE LINE\n" | |||
| val traces = mergeTraces(trace, chiselTrace).map(x => printMergedTraces((x), program)) | |||
| traces.map(_.mkString("\n")).mkString("\n", "\n--------------------------------------------------------------------------+------------------------------------------------------+-------------------------------\n", "\n") | |||
| "\n" + header + (traces.map(_.mkString("\n")).mkString("\n", "\n--------------------------------------------------------------------------+------------------------------------------------------+-------------------------------\n", "\n")) | |||
| } | |||
| } | |||
| @@ -75,7 +75,7 @@ object TestUtils { | |||
| val entry = hasLeft + (leftIndex << 1) + (hasRight << 8) + (rightIndex << 9) + (root.value << 16) | |||
| say(s"with leftIndex: ${leftIndex.hs}, rightIndex: ${rightIndex.hs}, value: ${root.value.hs} we got ${entry.hs}") | |||
| // say(s"with leftIndex: ${leftIndex.hs}, rightIndex: ${rightIndex.hs}, value: ${root.value.hs} we got ${entry.hs}") | |||
| entry :: foldAnno(root.left) ::: foldAnno(root.right) | |||
| }.getOrElse(Nil) | |||
| @@ -98,8 +98,8 @@ object TestUtils { | |||
| */ | |||
| def generateHazardsForward(steps: Int) : Unit = { | |||
| // val r = new scala.util.Random(0xF01D1EF7) | |||
| val r = new scala.util.Random(0xF01D1EF8) | |||
| val r = new scala.util.Random(0xF01D1EF7) | |||
| // val r = new scala.util.Random(0xF01D1EF8) | |||
| import Ops._ | |||
| val active = List(1, 2, 3) | |||
| @@ -136,9 +136,9 @@ object TestUtils { | |||
| (s"ori ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(imm).show}", ArithImm.or(rd, rs1, imm)), | |||
| (s"xori ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(imm).show}", ArithImm.xor(rd, rs1, imm)), | |||
| (s"andi ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(imm).show}", ArithImm.and(rd, rs1, imm)), | |||
| (s"slli ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(shift).show}", ArithImm.sll(rd, rs1, shift)), | |||
| (s"srli ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(shift).show}", ArithImm.srl(rd, rs1, shift)), | |||
| (s"srai ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(shift).show}", ArithImm.sra(rd, rs1, shift)), | |||
| (s"slli ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(math.abs(shift).toInt % 32).show}", ArithImmShift.sll(rd, rs1, math.abs(shift).toInt % 32)), | |||
| (s"srli ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(math.abs(shift).toInt % 32).show}", ArithImmShift.srl(rd, rs1, math.abs(shift).toInt % 32)), | |||
| (s"srai ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(math.abs(shift).toInt % 32).show}", ArithImmShift.sra(rd, rs1, math.abs(shift).toInt % 32)), | |||
| (s"slti ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(imm).show}", ArithImm.slt(rd, rs1, imm)), | |||
| (s"sltiu ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(imm).show}", ArithImm.sltu(rd, rs1, imm))) | |||
| (rd, choices.shuffle(r).head) | |||
| @@ -1,43 +0,0 @@ | |||
| // package FiveStage | |||
| // import chisel3._ | |||
| // import chisel3.iotesters._ | |||
| // import org.scalatest.{Matchers, FlatSpec} | |||
| // import spire.math.{UInt => Uint} | |||
| // import fileUtils._ | |||
| // import cats.implicits._ | |||
| // import RISCVutils._ | |||
| // import RISCVasm._ | |||
| // import riscala._ | |||
| // import utilz._ | |||
| // class AllTests extends FlatSpec with Matchers { | |||
| // val results = fileUtils.getAllTests.map{f => | |||
| // val result = TestRunner.runTest(f.getPath, false) | |||
| // (f.getName, result) | |||
| // } | |||
| // makeReport(results) | |||
| // } | |||
| // /** | |||
| // This is for you to run more verbose testing. | |||
| // */ | |||
| // class SelectedTests extends FlatSpec with Matchers { | |||
| // val tests = List( | |||
| // "matMul.s" | |||
| // ) | |||
| // if(!tests.isEmpty){ | |||
| // val results = fileUtils.getAllTests.filter(f => tests.contains(f.getName)).map{ f => | |||
| // val result = TestRunner.runTest(f.getPath, true) | |||
| // (f.getName, result) | |||
| // } | |||
| // makeReport(results) | |||
| // } | |||
| // } | |||