diff --git a/.gitignore b/.gitignore index 093805de..4df50ddf 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,10 @@ out .classpath .project examples/riscv + +# RARS build +build/ +rars.jar + +# macOS +.DS_Store diff --git a/examples/atomic_increment.s b/examples/atomic_increment.s new file mode 100644 index 00000000..01757c14 --- /dev/null +++ b/examples/atomic_increment.s @@ -0,0 +1,15 @@ +.globl main +.data +num: + .word 0x12345678 + +.text +main: + la t0, num +retry: + lr.w t1, (t0) + # increment by 1 + addi t1, t1, 1 + sc.w t2, t1, (t0) + # if save fails; retry operations again + bne zero, t2, retry diff --git a/src/images/Shared.png b/src/images/Shared.png new file mode 100644 index 00000000..320a5b1b Binary files /dev/null and b/src/images/Shared.png differ diff --git a/src/rars/Globals.java b/src/rars/Globals.java index 1696930d..efcb36f6 100644 --- a/src/rars/Globals.java +++ b/src/rars/Globals.java @@ -2,6 +2,7 @@ import rars.assembler.SymbolTable; import rars.riscv.hardware.Memory; +import rars.riscv.hardware.ReservationTables; import rars.riscv.InstructionSet; import rars.riscv.SyscallNumberOverride; import rars.util.PropertiesFile; @@ -68,6 +69,10 @@ public class Globals { * Simulated memory component. **/ public static Memory memory; + /** + * Simulated reservation tables component. + **/ + public static ReservationTables reservationTables; /** * Lock variable used at head of synchronized block to guard memory and registers **/ @@ -140,6 +145,11 @@ public class Globals { public static boolean runSpeedPanelExists = false; + private static int harts = 1; + + public static int getHarts() { + return harts; + } private static String getCopyrightYears() { return "2003-2019"; } @@ -166,7 +176,8 @@ public static Settings getSettings() { public static void initialize(boolean gui) { if (!initialized) { - memory = Memory.getInstance(); //clients can use Memory.getInstance instead of Globals.memory + memory = Memory.getInstance(); //clients can use Memory.getInstance instead of Globals.memory + reservationTables = new ReservationTables(harts); symbolTable = new SymbolTable("global"); settings = new Settings(gui); instructionSet = new InstructionSet(); diff --git a/src/rars/api/Program.java b/src/rars/api/Program.java index f0b0f0db..26897876 100644 --- a/src/rars/api/Program.java +++ b/src/rars/api/Program.java @@ -130,6 +130,7 @@ private ErrorList assemble(ArrayList programs) throws AssemblyExce */ public void setup(ArrayList args, String STDIN){ RegisterFile.resetRegisters(); + Globals.reservationTables.reset(); FloatingPointRegisterFile.resetRegisters(); ControlAndStatusRegisterFile.resetRegisters(); InterruptController.reset(); diff --git a/src/rars/riscv/BasicInstructionFormat.java b/src/rars/riscv/BasicInstructionFormat.java index c607e051..fce2261f 100644 --- a/src/rars/riscv/BasicInstructionFormat.java +++ b/src/rars/riscv/BasicInstructionFormat.java @@ -41,5 +41,5 @@ public enum BasicInstructionFormat { S_FORMAT, // 2 src registers + small immediate B_FORMAT, // 2 src registers + small immediate shifted left U_FORMAT, // 1 dst register + large immediate - J_FORMAT // 1 dst register + large immediate for jumping + J_FORMAT, // 1 dst register + large immediate for jumping } diff --git a/src/rars/riscv/hardware/ControlAndStatusRegisterFile.java b/src/rars/riscv/hardware/ControlAndStatusRegisterFile.java index bf1d88dc..0b4bfc66 100644 --- a/src/rars/riscv/hardware/ControlAndStatusRegisterFile.java +++ b/src/rars/riscv/hardware/ControlAndStatusRegisterFile.java @@ -70,13 +70,15 @@ public class ControlAndStatusRegisterFile { null, // cycleh null, // timeh null, // instreth + null, // mhartid }; tmp[1] = new LinkedRegister("fflags", 0x001, tmp[3], 0x1F); tmp[2] = new LinkedRegister("frm", 0x002, tmp[3], 0xE0); tmp[14] = new LinkedRegister("cycleh", 0xC80,tmp[11], 0xFFFFFFFF_00000000L); tmp[15] = new LinkedRegister("timeh", 0xC81, tmp[12],0xFFFFFFFF_00000000L); - tmp[16] = new LinkedRegister("instreth",0xC82, tmp[13],0xFFFFFFFF_00000000L); + tmp[16] = new LinkedRegister("instreth", 0xC82, tmp[13], 0xFFFFFFFF_00000000L); + tmp[17] = new ReadOnlyRegister("mhartid", 0xF10, 0); instance = new RegisterBlock('_', tmp); // prefix not used } diff --git a/src/rars/riscv/hardware/ReservationTable.java b/src/rars/riscv/hardware/ReservationTable.java new file mode 100644 index 00000000..1bee1ae8 --- /dev/null +++ b/src/rars/riscv/hardware/ReservationTable.java @@ -0,0 +1,108 @@ +package rars.riscv.hardware; + +import java.util.ArrayList; +import java.util.function.Predicate; + +/* +Copyright (c) 2021, Siva Chowdeswar Nandipati & Giancarlo Pernudi Segura. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject +to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +(MIT license, http://www.opensource.org/licenses/mit-license.html) + */ + +public class ReservationTable { + private ArrayList table; + public final static int capacity = 8; + private final static int doubleAlignMask = ~0x7; + + public enum bitWidth { + word, + doubleWord + } + + protected class ReservationTableEntry { + protected Integer address; + protected bitWidth width; + + public ReservationTableEntry(Integer address, bitWidth width) { + this.address = address; + this.width = width; + } + + public boolean equals(Object o) { + ReservationTableEntry other = (ReservationTableEntry) o; + return address.equals(other.address) && width.equals(other.width); + } + } + + public ReservationTable() { + table = new ArrayList(); + } + + public void reserveAddress(int address, bitWidth width) { + ReservationTableEntry newEntry = new ReservationTableEntry(address, width); + if(table.contains(newEntry)) + return; + if (table.size() == capacity) + table.remove(0); + table.add(newEntry); + } + + public void unreserveAddress(int address, bitWidth width) { + Predicate filter = entry -> + (entry.address == address && entry.width == width) + || ((address & doubleAlignMask) == entry.address && entry.width == bitWidth.doubleWord); + table.removeIf(filter); + } + + public boolean contains(int address, bitWidth width) { + for (ReservationTableEntry entry : table) { + if ((entry.address == address && entry.width == width) + || ((address & doubleAlignMask) == entry.address && entry.width == bitWidth.doubleWord)) + return true; + } + return false; + } + + public Integer[] getAddresses() { + Integer[] addresses = new Integer[capacity]; + for (int i = 0; i < capacity; i++) { + try { + addresses[i] = this.table.get(i).address; + } catch (IndexOutOfBoundsException e) { + addresses[i] = 0; + } + } + return addresses; + } + + public bitWidth[] getWidths() { + bitWidth[] addresses = new bitWidth[capacity]; + for (int i = 0; i < capacity; i++) { + try { + addresses[i] = this.table.get(i).width; + } catch (IndexOutOfBoundsException e) { + addresses[i] = null; + } + } + return addresses; + } +} diff --git a/src/rars/riscv/hardware/ReservationTables.java b/src/rars/riscv/hardware/ReservationTables.java new file mode 100644 index 00000000..398b0494 --- /dev/null +++ b/src/rars/riscv/hardware/ReservationTables.java @@ -0,0 +1,129 @@ +package rars.riscv.hardware; + +import java.util.Collection; +import java.util.Observable; +import java.util.Observer; +import java.util.Vector; + +import rars.SimulationException; +import rars.riscv.hardware.ReservationTable.bitWidth; + +/* +Copyright (c) 2021, Siva Chowdeswar Nandipati & Giancarlo Pernudi Segura. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject +to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +(MIT license, http://www.opensource.org/licenses/mit-license.html) + */ + +public class ReservationTables extends Observable { + private ReservationTable[] reservationTables; + public int harts; + private Collection observables = new Vector<>(); + + public ReservationTables(int harts) { + this.harts = harts; + reset(); + } + + public void reset() { + reservationTables = new ReservationTable[harts]; + for (int i = 0; i < reservationTables.length; i++) { + reservationTables[i] = new ReservationTable(); + } + } + + public void reserveAddress(int hart, int address, bitWidth width) throws AddressErrorException { + int modulo = width == bitWidth.doubleWord ? 8 : 4; + if (address % modulo != 0) { + throw new AddressErrorException("Reservation address not aligned to word boundary ", SimulationException.LOAD_ADDRESS_MISALIGNED, address); + } + reservationTables[hart].reserveAddress(address, width); + } + + public boolean unreserveAddress(int hart, int address, bitWidth width) throws AddressErrorException { + int modulo = width == bitWidth.doubleWord ? 8 : 4; + if (address % modulo != 0) { + throw new AddressErrorException("Reservation address not aligned to word boundary ", SimulationException.STORE_ADDRESS_MISALIGNED, address); + } + if (reservationTables[hart].contains(address, width)) { + for (ReservationTable reservationTable : reservationTables) { + reservationTable.unreserveAddress(address, width); + } + return true; + } + return false; + } + + public String[][] getAllAddressesAsStrings() { + String[][] all = new String[ReservationTable.capacity][harts * 2]; + char width = '0'; + for (int i = 0; i < ReservationTable.capacity; i++) { + for (int j = 0; j < harts; j++) { + Integer[] addresses = reservationTables[j].getAddresses(); + ReservationTable.bitWidth[] widths = reservationTables[j].getWidths(); + if (widths[i] == ReservationTable.bitWidth.word) { + width = 'w'; + } else if (widths[i] == ReservationTable.bitWidth.doubleWord) { + width = 'd'; + } else { + width = ' '; + } + all[i][j * 2] = String.format("0x%08x", addresses[i]); + all[i][j * 2 + 1] = String.format("%c", width); + } + } + return all; + } + + public void addObserver(Observer obs) { + observables.add(new ReservationTablesObservable(obs)); + } + + /** + * Remove specified reservation tables observer + * + * @param obs Observer to be removed + */ + public void deleteObserver(Observer obs) { + for (ReservationTablesObservable o : observables) { + o.deleteObserver(obs); + } + } + + /** + * Remove all reservation tables observers + */ + public void deleteObservers() { + // just drop the collection + observables = new Vector<>(); + } + + private class ReservationTablesObservable extends Observable { + public ReservationTablesObservable(Observer obs) { + this.addObserver(obs); + } + + public void notifyObserver(MemoryAccessNotice notice) { + this.setChanged(); + this.notifyObservers(notice); + } + } +} diff --git a/src/rars/riscv/instructions/AMOADDD.java b/src/rars/riscv/instructions/AMOADDD.java new file mode 100644 index 00000000..cef47d85 --- /dev/null +++ b/src/rars/riscv/instructions/AMOADDD.java @@ -0,0 +1,39 @@ +package rars.riscv.instructions; + +/* +Copyright (c) 2021, Giancarlo Pernudi Segura + +Developed by Giancarlo Pernudi Segura at the University of Alberta (pernudi@ualberta.ca) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject +to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +(MIT license, http://www.opensource.org/licenses/mit-license.html) + */ + +public class AMOADDD extends AtomicMemoryOperation { + public AMOADDD() { + super("amoadd.d t0, t1, (t2)", "Loads value at t2 and places it into t0, adds value t1 and t0 (new), and saves at memory location t2.", "00000", true); + } + + @Override + protected long binaryOperation(long value1, long value2) { + return value1 + value2; + } +} diff --git a/src/rars/riscv/instructions/AMOADDW.java b/src/rars/riscv/instructions/AMOADDW.java new file mode 100644 index 00000000..8cad4e46 --- /dev/null +++ b/src/rars/riscv/instructions/AMOADDW.java @@ -0,0 +1,39 @@ +package rars.riscv.instructions; + +/* +Copyright (c) 2021, Giancarlo Pernudi Segura + +Developed by Giancarlo Pernudi Segura at the University of Alberta (pernudi@ualberta.ca) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject +to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +(MIT license, http://www.opensource.org/licenses/mit-license.html) + */ + +public class AMOADDW extends AtomicMemoryOperation { + public AMOADDW() { + super("amoadd.w t0, t1, (t2)", "Loads value at t2 and places it into t0, adds value t1 and t0 (new), and saves at memory location t2.", "00000"); + } + + @Override + protected long binaryOperation(long value1, long value2) { + return value1 + value2; + } +} diff --git a/src/rars/riscv/instructions/AMOANDD.java b/src/rars/riscv/instructions/AMOANDD.java new file mode 100644 index 00000000..ca9b07af --- /dev/null +++ b/src/rars/riscv/instructions/AMOANDD.java @@ -0,0 +1,39 @@ +package rars.riscv.instructions; + +/* +Copyright (c) 2021, Giancarlo Pernudi Segura + +Developed by Giancarlo Pernudi Segura at the University of Alberta (pernudi@ualberta.ca) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject +to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +(MIT license, http://www.opensource.org/licenses/mit-license.html) + */ + +public class AMOANDD extends AtomicMemoryOperation { + public AMOANDD() { + super("amoand.d t0, t1, (t2)", "Loads value at t2 and places it into t0, ANDS value t1 and t0 (new), and saves at memory location t2.", "01100", true); + } + + @Override + protected long binaryOperation(long value1, long value2) { + return value1 & value2; + } +} diff --git a/src/rars/riscv/instructions/AMOANDW.java b/src/rars/riscv/instructions/AMOANDW.java new file mode 100644 index 00000000..ade22070 --- /dev/null +++ b/src/rars/riscv/instructions/AMOANDW.java @@ -0,0 +1,39 @@ +package rars.riscv.instructions; + +/* +Copyright (c) 2021, Giancarlo Pernudi Segura + +Developed by Giancarlo Pernudi Segura at the University of Alberta (pernudi@ualberta.ca) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject +to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +(MIT license, http://www.opensource.org/licenses/mit-license.html) + */ + +public class AMOANDW extends AtomicMemoryOperation { + public AMOANDW() { + super("amoand.w t0, t1, (t2)", "Loads value at t2 and places it into t0, ANDS value t1 and t0 (new), and saves at memory location t2.", "01100"); + } + + @Override + protected long binaryOperation(long value1, long value2) { + return value1 & value2; + } +} diff --git a/src/rars/riscv/instructions/AMOMAXD.java b/src/rars/riscv/instructions/AMOMAXD.java new file mode 100644 index 00000000..7f6de467 --- /dev/null +++ b/src/rars/riscv/instructions/AMOMAXD.java @@ -0,0 +1,39 @@ +package rars.riscv.instructions; + +/* +Copyright (c) 2021, Giancarlo Pernudi Segura + +Developed by Giancarlo Pernudi Segura at the University of Alberta (pernudi@ualberta.ca) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject +to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +(MIT license, http://www.opensource.org/licenses/mit-license.html) + */ + +public class AMOMAXD extends AtomicMemoryOperation { + public AMOMAXD() { + super("amomax.d t0, t1, (t2)", "Loads value at t2 and places it into t0, and saves at memory location t2, the greatest value between value t1 and t0 (new).", "10100", true); + } + + @Override + protected long binaryOperation(long value1, long value2) { + return Long.max(value1, value2); + } +} diff --git a/src/rars/riscv/instructions/AMOMAXUD.java b/src/rars/riscv/instructions/AMOMAXUD.java new file mode 100644 index 00000000..eee095e9 --- /dev/null +++ b/src/rars/riscv/instructions/AMOMAXUD.java @@ -0,0 +1,39 @@ +package rars.riscv.instructions; + +/* +Copyright (c) 2021, Giancarlo Pernudi Segura + +Developed by Giancarlo Pernudi Segura at the University of Alberta (pernudi@ualberta.ca) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject +to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +(MIT license, http://www.opensource.org/licenses/mit-license.html) + */ + +public class AMOMAXUD extends AtomicMemoryOperation { + public AMOMAXUD() { + super("amomaxu.d t0, t1, (t2)", "Loads value at t2 and places it into t0, and saves at memory location t2, the greatest unsigned value between value t1 and t0 (new).", "11100", true); + } + + @Override + protected long binaryOperation(long value1, long value2) { + return Long.compareUnsigned(value1, value2) > 0 ? value1 : value2; + } +} diff --git a/src/rars/riscv/instructions/AMOMAXUW.java b/src/rars/riscv/instructions/AMOMAXUW.java new file mode 100644 index 00000000..e9a13139 --- /dev/null +++ b/src/rars/riscv/instructions/AMOMAXUW.java @@ -0,0 +1,39 @@ +package rars.riscv.instructions; + +/* +Copyright (c) 2021, Giancarlo Pernudi Segura + +Developed by Giancarlo Pernudi Segura at the University of Alberta (pernudi@ualberta.ca) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject +to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +(MIT license, http://www.opensource.org/licenses/mit-license.html) + */ + +public class AMOMAXUW extends AtomicMemoryOperation { + public AMOMAXUW() { + super("amomaxu.w t0, t1, (t2)", "Loads value at t2 and places it into t0, and saves at memory location t2, the greatest unsigned value between value t1 and t0 (new).", "11100"); + } + + @Override + protected long binaryOperation(long value1, long value2) { + return Long.compareUnsigned(value1, value2) > 0 ? value1 : value2; + } +} diff --git a/src/rars/riscv/instructions/AMOMAXW.java b/src/rars/riscv/instructions/AMOMAXW.java new file mode 100644 index 00000000..fe20615f --- /dev/null +++ b/src/rars/riscv/instructions/AMOMAXW.java @@ -0,0 +1,39 @@ +package rars.riscv.instructions; + +/* +Copyright (c) 2021, Giancarlo Pernudi Segura + +Developed by Giancarlo Pernudi Segura at the University of Alberta (pernudi@ualberta.ca) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject +to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +(MIT license, http://www.opensource.org/licenses/mit-license.html) + */ + +public class AMOMAXW extends AtomicMemoryOperation { + public AMOMAXW() { + super("amomax.w t0, t1, (t2)", "Loads value at t2 and places it into t0, and saves at memory location t2, the greatest value between value t1 and t0 (new).", "10100"); + } + + @Override + protected long binaryOperation(long value1, long value2) { + return Long.max(value1, value2); + } +} diff --git a/src/rars/riscv/instructions/AMOMIND.java b/src/rars/riscv/instructions/AMOMIND.java new file mode 100644 index 00000000..a339e477 --- /dev/null +++ b/src/rars/riscv/instructions/AMOMIND.java @@ -0,0 +1,39 @@ +package rars.riscv.instructions; + +/* +Copyright (c) 2021, Giancarlo Pernudi Segura + +Developed by Giancarlo Pernudi Segura at the University of Alberta (pernudi@ualberta.ca) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject +to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +(MIT license, http://www.opensource.org/licenses/mit-license.html) + */ + +public class AMOMIND extends AtomicMemoryOperation { + public AMOMIND() { + super("amomin.d t0, t1, (t2)", "Loads value at t2 and places it into t0, and saves at memory location t2, the lowest value between value t1 and t0 (new).", "10000", true); + } + + @Override + protected long binaryOperation(long value1, long value2) { + return Long.min(value1, value2); + } +} diff --git a/src/rars/riscv/instructions/AMOMINUD.java b/src/rars/riscv/instructions/AMOMINUD.java new file mode 100644 index 00000000..3f4e5348 --- /dev/null +++ b/src/rars/riscv/instructions/AMOMINUD.java @@ -0,0 +1,39 @@ +package rars.riscv.instructions; + +/* +Copyright (c) 2021, Giancarlo Pernudi Segura + +Developed by Giancarlo Pernudi Segura at the University of Alberta (pernudi@ualberta.ca) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject +to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +(MIT license, http://www.opensource.org/licenses/mit-license.html) + */ + +public class AMOMINUD extends AtomicMemoryOperation { + public AMOMINUD() { + super("amominu.d t0, t1, (t2)", "Loads value at t2 and places it into t0, and saves at memory location t2, the lowest unsigned value between value t1 and t0 (new).", "11000", true); + } + + @Override + protected long binaryOperation(long value1, long value2) { + return Long.compareUnsigned(value1, value2) < 0 ? value1 : value2; + } +} diff --git a/src/rars/riscv/instructions/AMOMINUW.java b/src/rars/riscv/instructions/AMOMINUW.java new file mode 100644 index 00000000..c9ed5836 --- /dev/null +++ b/src/rars/riscv/instructions/AMOMINUW.java @@ -0,0 +1,39 @@ +package rars.riscv.instructions; + +/* +Copyright (c) 2021, Giancarlo Pernudi Segura + +Developed by Giancarlo Pernudi Segura at the University of Alberta (pernudi@ualberta.ca) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject +to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +(MIT license, http://www.opensource.org/licenses/mit-license.html) + */ + +public class AMOMINUW extends AtomicMemoryOperation { + public AMOMINUW() { + super("amominu.w t0, t1, (t2)", "Loads value at t2 and places it into t0, and saves at memory location t2, the lowest unsigned value between value t1 and t0 (new).", "11000"); + } + + @Override + protected long binaryOperation(long value1, long value2) { + return Long.compareUnsigned(value1, value2) < 0 ? value1 : value2; + } +} diff --git a/src/rars/riscv/instructions/AMOMINW.java b/src/rars/riscv/instructions/AMOMINW.java new file mode 100644 index 00000000..f2f6d153 --- /dev/null +++ b/src/rars/riscv/instructions/AMOMINW.java @@ -0,0 +1,39 @@ +package rars.riscv.instructions; + +/* +Copyright (c) 2021, Giancarlo Pernudi Segura + +Developed by Giancarlo Pernudi Segura at the University of Alberta (pernudi@ualberta.ca) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject +to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +(MIT license, http://www.opensource.org/licenses/mit-license.html) + */ + +public class AMOMINW extends AtomicMemoryOperation { + public AMOMINW() { + super("amomin.w t0, t1, (t2)", "Loads value at t2 and places it into t0, and saves at memory location t2, the lowest value between value t1 and t0 (new).", "10000"); + } + + @Override + protected long binaryOperation(long value1, long value2) { + return Long.min(value1, value2); + } +} diff --git a/src/rars/riscv/instructions/AMOORD.java b/src/rars/riscv/instructions/AMOORD.java new file mode 100644 index 00000000..31a820ab --- /dev/null +++ b/src/rars/riscv/instructions/AMOORD.java @@ -0,0 +1,39 @@ +package rars.riscv.instructions; + +/* +Copyright (c) 2021, Giancarlo Pernudi Segura + +Developed by Giancarlo Pernudi Segura at the University of Alberta (pernudi@ualberta.ca) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject +to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +(MIT license, http://www.opensource.org/licenses/mit-license.html) + */ + +public class AMOORD extends AtomicMemoryOperation { + public AMOORD() { + super("amoor.d t0, t1, (t2)", "Loads value at t2 and places it into t0, ORS value t1 and t0 (new), and saves at memory location t2.", "01000", true); + } + + @Override + protected long binaryOperation(long value1, long value2) { + return value1 | value2; + } +} diff --git a/src/rars/riscv/instructions/AMOORW.java b/src/rars/riscv/instructions/AMOORW.java new file mode 100644 index 00000000..8b97511a --- /dev/null +++ b/src/rars/riscv/instructions/AMOORW.java @@ -0,0 +1,39 @@ +package rars.riscv.instructions; + +/* +Copyright (c) 2021, Giancarlo Pernudi Segura + +Developed by Giancarlo Pernudi Segura at the University of Alberta (pernudi@ualberta.ca) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject +to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +(MIT license, http://www.opensource.org/licenses/mit-license.html) + */ + +public class AMOORW extends AtomicMemoryOperation { + public AMOORW() { + super("amoor.w t0, t1, (t2)", "Loads value at t2 and places it into t0, ORS value t1 and t0 (new), and saves at memory location t2.", "01000"); + } + + @Override + protected long binaryOperation(long value1, long value2) { + return value1 | value2; + } +} diff --git a/src/rars/riscv/instructions/AMOSWAPD.java b/src/rars/riscv/instructions/AMOSWAPD.java new file mode 100644 index 00000000..0cdccb0b --- /dev/null +++ b/src/rars/riscv/instructions/AMOSWAPD.java @@ -0,0 +1,39 @@ +package rars.riscv.instructions; + +/* +Copyright (c) 2021, Giancarlo Pernudi Segura + +Developed by Giancarlo Pernudi Segura at the University of Alberta (pernudi@ualberta.ca) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject +to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +(MIT license, http://www.opensource.org/licenses/mit-license.html) + */ + +public class AMOSWAPD extends AtomicMemoryOperation { + public AMOSWAPD() { + super("amoswap.d t0, t1, (t2)", "Loads value at t2 and places it into t0, saves value t1 at memory location t2.", "00001", true); + } + + @Override + protected long binaryOperation(long value1, long value2) { + return value2; + } +} diff --git a/src/rars/riscv/instructions/AMOSWAPW.java b/src/rars/riscv/instructions/AMOSWAPW.java new file mode 100644 index 00000000..f2522a29 --- /dev/null +++ b/src/rars/riscv/instructions/AMOSWAPW.java @@ -0,0 +1,39 @@ +package rars.riscv.instructions; + +/* +Copyright (c) 2021, Giancarlo Pernudi Segura + +Developed by Giancarlo Pernudi Segura at the University of Alberta (pernudi@ualberta.ca) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject +to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +(MIT license, http://www.opensource.org/licenses/mit-license.html) + */ + +public class AMOSWAPW extends AtomicMemoryOperation { + public AMOSWAPW() { + super("amoswap.w t0, t1, (t2)", "Loads value at t2 and places it into t0, saves value t1 at memory location t2.", "00001"); + } + + @Override + protected long binaryOperation(long value1, long value2) { + return value2; + } +} diff --git a/src/rars/riscv/instructions/AMOXORD.java b/src/rars/riscv/instructions/AMOXORD.java new file mode 100644 index 00000000..5e558c75 --- /dev/null +++ b/src/rars/riscv/instructions/AMOXORD.java @@ -0,0 +1,39 @@ +package rars.riscv.instructions; + +/* +Copyright (c) 2021, Giancarlo Pernudi Segura + +Developed by Giancarlo Pernudi Segura at the University of Alberta (pernudi@ualberta.ca) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject +to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +(MIT license, http://www.opensource.org/licenses/mit-license.html) + */ + +public class AMOXORD extends AtomicMemoryOperation { + public AMOXORD() { + super("amoxor.d t0, t1, (t2)", "Loads value at t2 and places it into t0, XORS value t1 and t0 (new), and saves at memory location t2.", "00100", true); + } + + @Override + protected long binaryOperation(long value1, long value2) { + return value1 ^ value2; + } +} diff --git a/src/rars/riscv/instructions/AMOXORW.java b/src/rars/riscv/instructions/AMOXORW.java new file mode 100644 index 00000000..10dc0759 --- /dev/null +++ b/src/rars/riscv/instructions/AMOXORW.java @@ -0,0 +1,39 @@ +package rars.riscv.instructions; + +/* +Copyright (c) 2021, Giancarlo Pernudi Segura + +Developed by Giancarlo Pernudi Segura at the University of Alberta (pernudi@ualberta.ca) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject +to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +(MIT license, http://www.opensource.org/licenses/mit-license.html) + */ + +public class AMOXORW extends AtomicMemoryOperation { + public AMOXORW() { + super("amoxor.w t0, t1, (t2)", "Loads value at t2 and places it into t0, XORS value t1 and t0 (new), and saves at memory location t2.", "00100"); + } + + @Override + protected long binaryOperation(long value1, long value2) { + return value1 ^ value2; + } +} diff --git a/src/rars/riscv/instructions/Atomic.java b/src/rars/riscv/instructions/Atomic.java new file mode 100644 index 00000000..8cd2cf2b --- /dev/null +++ b/src/rars/riscv/instructions/Atomic.java @@ -0,0 +1,49 @@ +package rars.riscv.instructions; + +import rars.riscv.BasicInstruction; +import rars.riscv.BasicInstructionFormat; + +/* +Copyright (c) 2021, Giancarlo Pernudi Segura + +Developed by Giancarlo Pernudi Segura at the University of Alberta (pernudi@ualberta.ca) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject +to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +(MIT license, http://www.opensource.org/licenses/mit-license.html) + */ + +/** + * Base class for all Atomic instructions + * + * @author Giancarlo Pernudi Segura + * @version May 2017 + */ +public abstract class Atomic extends BasicInstruction { + public Atomic(String usage, String description, String funct3, String funct5) { + super(usage, description, BasicInstructionFormat.R_FORMAT, + funct5 + " 00sssss ttttt " + funct3 + " fffff 0101111"); + } + + public Atomic(String usage, String description, String funct3, String funct5, boolean rv64) { + super(usage, description, BasicInstructionFormat.R_FORMAT, + funct5 + " 00sssss ttttt " + funct3 + " fffff 0101111", rv64); + } +} diff --git a/src/rars/riscv/instructions/AtomicMemoryOperation.java b/src/rars/riscv/instructions/AtomicMemoryOperation.java new file mode 100644 index 00000000..655cfac8 --- /dev/null +++ b/src/rars/riscv/instructions/AtomicMemoryOperation.java @@ -0,0 +1,77 @@ +package rars.riscv.instructions; + +import rars.Globals; +import rars.ProgramStatement; +import rars.SimulationException; +import rars.riscv.InstructionSet; +import rars.riscv.hardware.AddressErrorException; +import rars.riscv.hardware.RegisterFile; +import rars.riscv.hardware.ReservationTable.bitWidth; + +/* +Copyright (c) 2021, Giancarlo Pernudi Segura + +Developed by Giancarlo Pernudi Segura at the University of Alberta (pernudi@ualberta.ca) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject +to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +(MIT license, http://www.opensource.org/licenses/mit-license.html) + */ + +/** + * Base class for all Atomic instructions + * + * @author Giancarlo Pernudi Segura + * @version May 2017 + */ +public abstract class AtomicMemoryOperation extends Atomic { + private bitWidth width; + + public AtomicMemoryOperation(String usage, String description, String funct5) { + super(usage, description, "010", funct5); + width = bitWidth.word; + } + + public AtomicMemoryOperation(String usage, String description, String funct5, boolean rv64) { + super(usage, description, rv64 ? "011" : "010", funct5, rv64); + width = rv64 ? bitWidth.doubleWord : bitWidth.word; + } + + public void simulate(ProgramStatement statement) throws SimulationException { + int[] operands = statement.getOperands(); + try { + int rs1Loc = RegisterFile.getValue(operands[2]); + Globals.reservationTables.unreserveAddress(0, rs1Loc, width); + long rs1Data = InstructionSet.rv64 ? Globals.memory.getDoubleWord(rs1Loc) : Globals.memory.getWord(rs1Loc); + long rs2Value = RegisterFile.getValueLong(operands[1]); + RegisterFile.updateRegister(operands[0], rs1Data); + rs1Data = binaryOperation(rs1Data, rs2Value); + if (InstructionSet.rv64) { + Globals.memory.setDoubleWord(rs1Loc, rs1Data); + } else { + Globals.memory.setWord(rs1Loc, (int) rs1Data); + } + } catch (AddressErrorException e) { + throw new SimulationException(statement, e); + } + } + + protected abstract long binaryOperation(long value1, long value2); +} diff --git a/src/rars/riscv/instructions/LRD.java b/src/rars/riscv/instructions/LRD.java new file mode 100644 index 00000000..16d702e0 --- /dev/null +++ b/src/rars/riscv/instructions/LRD.java @@ -0,0 +1,28 @@ +package rars.riscv.instructions; + +import rars.Globals; +import rars.riscv.hardware.AddressErrorException; +import rars.ProgramStatement; +import rars.SimulationException; +import rars.riscv.hardware.RegisterFile; +import rars.riscv.hardware.ReservationTable.bitWidth; + +public class LRD extends Atomic { + public LRD() { + super("lr.d t1, (t2)", "Set t1 to contents of effective memory word address and reserve", "011", "00010", true); + } + + public void simulate(ProgramStatement statement) throws SimulationException { + int[] operands = statement.getOperands(); + try { + RegisterFile.updateRegister(operands[0], load(RegisterFile.getValue(operands[1]))); + } catch (AddressErrorException e) { + throw new SimulationException(statement, e); + } + } + + private long load(int address) throws AddressErrorException { + Globals.reservationTables.reserveAddress(0, address, bitWidth.doubleWord); + return Globals.memory.getDoubleWord(address); + } +} diff --git a/src/rars/riscv/instructions/LRW.java b/src/rars/riscv/instructions/LRW.java new file mode 100644 index 00000000..0d433abc --- /dev/null +++ b/src/rars/riscv/instructions/LRW.java @@ -0,0 +1,28 @@ +package rars.riscv.instructions; + +import rars.Globals; +import rars.riscv.hardware.AddressErrorException; +import rars.ProgramStatement; +import rars.SimulationException; +import rars.riscv.hardware.RegisterFile; +import rars.riscv.hardware.ReservationTable.bitWidth; + +public class LRW extends Atomic { + public LRW() { + super("lr.w t1, (t2)", "Set t1 to contents of effective memory word address and reserve", "010", "00010"); + } + + public void simulate(ProgramStatement statement) throws SimulationException { + int[] operands = statement.getOperands(); + try { + RegisterFile.updateRegister(operands[0], load(RegisterFile.getValue(operands[1]))); + } catch (AddressErrorException e) { + throw new SimulationException(statement, e); + } + } + + private long load(int address) throws AddressErrorException { + Globals.reservationTables.reserveAddress(0, address, bitWidth.word); + return Globals.memory.getWord(address); + } +} diff --git a/src/rars/riscv/instructions/SB.java b/src/rars/riscv/instructions/SB.java index bc8f3446..9768ff64 100644 --- a/src/rars/riscv/instructions/SB.java +++ b/src/rars/riscv/instructions/SB.java @@ -2,6 +2,7 @@ import rars.Globals; import rars.riscv.hardware.AddressErrorException; +import rars.riscv.hardware.ReservationTable.bitWidth; /* Copyright (c) 2017, Benjamin Landers @@ -36,9 +37,7 @@ public SB() { } public void store(int address, long data) throws AddressErrorException { + Globals.reservationTables.unreserveAddress(0, address & ~0b11, bitWidth.word); Globals.memory.setByte(address, (int)data & 0x000000FF); } } - - - diff --git a/src/rars/riscv/instructions/SCD.java b/src/rars/riscv/instructions/SCD.java new file mode 100644 index 00000000..dba28da1 --- /dev/null +++ b/src/rars/riscv/instructions/SCD.java @@ -0,0 +1,32 @@ +package rars.riscv.instructions; + +import rars.Globals; +import rars.riscv.hardware.AddressErrorException; +import rars.ProgramStatement; +import rars.SimulationException; +import rars.riscv.hardware.RegisterFile; +import rars.riscv.hardware.ReservationTable.bitWidth; + +public class SCD extends Atomic { + public SCD() { + super("sc.d t0, t1, (t2)", "Try to store t1 to contents of effective memory word address, sets t0 to store attempt result", "011", "00011", true); + } + + public void simulate(ProgramStatement statement) throws SimulationException { + int[] operands = statement.getOperands(); + try { + long result = store(RegisterFile.getValue(operands[2]), RegisterFile.getValue(operands[1])); + RegisterFile.updateRegister(operands[0], result); + } catch (AddressErrorException e) { + throw new SimulationException(statement, e); + } + } + + private long store(int address, int value) throws AddressErrorException { + if (Globals.reservationTables.unreserveAddress(0, address, bitWidth.doubleWord)) { + Globals.memory.setDoubleWord(address, value); + return 0; + } + return 1; + } +} diff --git a/src/rars/riscv/instructions/SCW.java b/src/rars/riscv/instructions/SCW.java new file mode 100644 index 00000000..80ad716c --- /dev/null +++ b/src/rars/riscv/instructions/SCW.java @@ -0,0 +1,32 @@ +package rars.riscv.instructions; + +import rars.Globals; +import rars.riscv.hardware.AddressErrorException; +import rars.ProgramStatement; +import rars.SimulationException; +import rars.riscv.hardware.RegisterFile; +import rars.riscv.hardware.ReservationTable.bitWidth; + +public class SCW extends Atomic { + public SCW() { + super("sc.w t0, t1, (t2)", "Try to store t1 to contents of effective memory word address, sets t0 to store attempt result", "010", "00011"); + } + + public void simulate(ProgramStatement statement) throws SimulationException { + int[] operands = statement.getOperands(); + try { + int result = store(RegisterFile.getValue(operands[2]), RegisterFile.getValue(operands[1])); + RegisterFile.updateRegister(operands[0], result); + } catch (AddressErrorException e) { + throw new SimulationException(statement, e); + } + } + + private int store(int address, int value) throws AddressErrorException { + if (Globals.reservationTables.unreserveAddress(0, address, bitWidth.word)) { + Globals.memory.setWord(address, value); + return 0; + } + return 1; + } +} diff --git a/src/rars/riscv/instructions/SD.java b/src/rars/riscv/instructions/SD.java index 20228068..4b901d8d 100644 --- a/src/rars/riscv/instructions/SD.java +++ b/src/rars/riscv/instructions/SD.java @@ -2,6 +2,7 @@ import rars.Globals; import rars.riscv.hardware.AddressErrorException; +import rars.riscv.hardware.ReservationTable.bitWidth; public class SD extends Store { public SD() { @@ -9,9 +10,7 @@ public SD() { } public void store(int address, long data) throws AddressErrorException { + Globals.reservationTables.unreserveAddress(0, address, bitWidth.doubleWord); Globals.memory.setDoubleWord(address, data); } } - - - diff --git a/src/rars/riscv/instructions/SH.java b/src/rars/riscv/instructions/SH.java index 829b6cba..a640e1f5 100644 --- a/src/rars/riscv/instructions/SH.java +++ b/src/rars/riscv/instructions/SH.java @@ -2,6 +2,7 @@ import rars.Globals; import rars.riscv.hardware.AddressErrorException; +import rars.riscv.hardware.ReservationTable.bitWidth; /* Copyright (c) 2017, Benjamin Landers @@ -36,9 +37,7 @@ public SH() { } public void store(int address, long data) throws AddressErrorException { + Globals.reservationTables.unreserveAddress(0, address & ~0b11, bitWidth.word); Globals.memory.setHalf(address, (int)data & 0x0000FFFF); } } - - - diff --git a/src/rars/riscv/instructions/SW.java b/src/rars/riscv/instructions/SW.java index 73b3ca65..9c1720cf 100644 --- a/src/rars/riscv/instructions/SW.java +++ b/src/rars/riscv/instructions/SW.java @@ -2,6 +2,7 @@ import rars.Globals; import rars.riscv.hardware.AddressErrorException; +import rars.riscv.hardware.ReservationTable.bitWidth; /* Copyright (c) 2017, Benjamin Landers @@ -36,9 +37,7 @@ public SW() { } public void store(int address, long data) throws AddressErrorException { + Globals.reservationTables.unreserveAddress(0, address, bitWidth.word); Globals.memory.setWord(address, (int) data); } } - - - diff --git a/src/rars/tools/AbstractToolAndApplication.java b/src/rars/tools/AbstractToolAndApplication.java index 2ef1518c..f5fca64a 100644 --- a/src/rars/tools/AbstractToolAndApplication.java +++ b/src/rars/tools/AbstractToolAndApplication.java @@ -68,7 +68,6 @@ public abstract class AbstractToolAndApplication extends JFrame implements Tool, protected boolean isBeingUsedAsATool = false; // can use to determine whether invoked as Tool or stand-alone. private JDialog dialog; // used only for Tool use. This is the pop-up dialog that appears when menu item selected. protected Window theWindow; // highest level GUI component (a JFrame for app, a JDialog for Tool) - // Major GUI components private JLabel headingLabel; private String title; // descriptive title for title bar provided to constructor. diff --git a/src/rars/tools/InstructionStatistics.java b/src/rars/tools/InstructionStatistics.java index ef96d88d..dde83937 100644 --- a/src/rars/tools/InstructionStatistics.java +++ b/src/rars/tools/InstructionStatistics.java @@ -226,7 +226,7 @@ protected void addAsObserver() { * decodes the instruction and determines the category of the instruction. *

* The instruction is decoded by checking the java instance of the instruction. - * Only the most relevant instructions are decoded and categorized. + * Supported instructions are RV32I, RV64I, M, and A extensions. * * @param instruction the instruction to decode * @return the category of the instruction @@ -259,6 +259,8 @@ protected int getInstructionCategory(Instruction instruction) { return InstructionStatistics.CATEGORY_MEM; // lb, lh, lwl, lw, lbu, lhu, lwr if (instruction instanceof Store) return InstructionStatistics.CATEGORY_MEM; // sb, sh, swl, sw, swr + if (instruction instanceof Atomic) + return InstructionStatistics.CATEGORY_MEM; // a extension return InstructionStatistics.CATEGORY_OTHER; } diff --git a/src/rars/tools/ReservationTablesTool.java b/src/rars/tools/ReservationTablesTool.java new file mode 100644 index 00000000..0c29b6b2 --- /dev/null +++ b/src/rars/tools/ReservationTablesTool.java @@ -0,0 +1,151 @@ +package rars.tools; + +import rars.Globals; +import rars.riscv.hardware.AddressErrorException; +import rars.riscv.hardware.ReservationTable.bitWidth; +import rars.venus.*; + +import javax.swing.*; +import java.awt.*; +import java.util.*; +import java.awt.event.*; +import javax.swing.border.TitledBorder; + +/* +Copyright (c) 2021, Giancarlo Pernudi Segura & Siva Chowdeswar Nandipati. + +Developed by Giancarlo Pernudi Segura (pernudi@ualberta.ca) & Siva Chowdeswar Nandipati (sivachow@ualberta.ca). + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject +to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +(MIT license, http://www.opensource.org/licenses/mit-license.html) + */ + +public class ReservationTablesTool extends AbstractToolAndApplication { + private static String heading = "Reservation Table Tool"; + private static String version = "Version 1.0"; + private static String displayPanelTitle; + private JPanel displayOptions, hartPanel; + + private JTable reservations; + + public ReservationTablesTool() { + super(heading + ", " + version, heading); + Globals.reservationTables.addObserver(this); + } + + protected JComponent buildMainDisplayArea() { + JPanel panelTools = new JPanel(new BorderLayout()); + hartPanel = new JPanel(new BorderLayout()); + String[] columns = new String[Globals.reservationTables.harts * 2]; + for (int i = 0; i < Globals.reservationTables.harts; i++) { + columns[i * 2] = String.format("Hart %d", i); + columns[i * 2 + 1] = "Length"; + } + reservations = new JTable(Globals.reservationTables.getAllAddressesAsStrings(), columns) { + @Override + public boolean isCellEditable(int row, int column) { + return false; + } + }; + + hartPanel.add(reservations.getTableHeader(), BorderLayout.NORTH); + reservations.setCellSelectionEnabled(true); + reservations.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + reservations.getTableHeader().setReorderingAllowed(false); + hartPanel.add(reservations); + + TitledBorder tb = new TitledBorder(displayPanelTitle); + tb.setTitleJustification(TitledBorder.CENTER); + panelTools.setBorder(tb); + + Box displayOptions = Box.createHorizontalBox(); + + JButton clearButton = new JButton("Clear Selected"); + clearButton.setToolTipText("Clear the Selected from the Reserve Table"); + clearButton.addActionListener(l -> { + if (connectButton.isConnected()) { + int row = reservations.getSelectedRow(); + int col = reservations.getSelectedColumn(); + if(row < 0 || col < 0) + return; + if (col % 2 == 1) + col--; + int address = Integer.parseInt(reservations.getValueAt(row, col) + .toString().substring(2), 16); + try { + Globals.reservationTables.unreserveAddress(col, address, bitWidth.word); + } catch (AddressErrorException e) { + e.printStackTrace(); + } + } + reservations.clearSelection(); + updateDisplay(); + }); + + clearButton.addKeyListener(new EnterKeyListener(clearButton)); + displayOptions.add(Box.createHorizontalGlue()); + displayOptions.add(clearButton); + displayOptions.add(Box.createHorizontalGlue()); + + JSplitPane both = new JSplitPane(JSplitPane.VERTICAL_SPLIT, hartPanel, displayOptions); + both.setResizeWeight(0.5); + panelTools.add(both); + return panelTools; + } + + + @Override + public String getName() { + return heading; + } + + protected JComponent getHelpComponent() { + final String helpContent = "Use this tool to simulate atomic operations such as store conditional.\n" + + "While this tool is connected to the program, the table below shows the\n" + + "reservation table for each hart. Addresses reserved by a hart\n" + + "will appear under that hart's column. You can release an address,\n" + + "which will release that address across all the hart's tables in\n" + + "order to simulate some other hart performing a store conditional.\n" + + "(contributed by Giancarlo Pernudi Segura, pernudi@ualberta.ca) &" + + "\n Siva Chowdeswar Nandipati (sivachow@ualberta.ca)"; + JButton help = new JButton("Help"); + help.addActionListener(l -> { + JOptionPane.showMessageDialog(theWindow, helpContent); + }); + return help; + } + + @Override + protected void updateDisplay() { + String[][] addresses = Globals.reservationTables.getAllAddressesAsStrings(); + for (int i = 0; i < addresses.length; i++) { + for (int j = 0; j < addresses[i].length; j++) { + reservations.setValueAt(addresses[i][j], i, j); + } + } + } + + @Override + protected void reset() { + Globals.reservationTables.reset(); + updateDisplay(); + } +} diff --git a/src/rars/venus/registers/ControlAndStatusWindow.java b/src/rars/venus/registers/ControlAndStatusWindow.java index 3fb21358..743ad022 100644 --- a/src/rars/venus/registers/ControlAndStatusWindow.java +++ b/src/rars/venus/registers/ControlAndStatusWindow.java @@ -28,7 +28,8 @@ public class ControlAndStatusWindow extends RegisterBlockWindow { /*instret*/"Instructions retired (same as cycle in RARS)", /*cycleh*/ "High 32 bits of cycle", /*timeh*/ "High 32 bits of time", - /*instreth*/ "High 32 bits of instret" + /*instreth*/ "High 32 bits of instret", + /*mhartid*/"ID of the hardware thread running the code" }; public ControlAndStatusWindow() { @@ -54,4 +55,4 @@ protected void endObserving() { public void resetRegisters() { ControlAndStatusRegisterFile.resetRegisters(); } -} \ No newline at end of file +} diff --git a/src/rars/venus/registers/RegisterBlockWindow.java b/src/rars/venus/registers/RegisterBlockWindow.java index 7c94713e..0550261f 100644 --- a/src/rars/venus/registers/RegisterBlockWindow.java +++ b/src/rars/venus/registers/RegisterBlockWindow.java @@ -61,6 +61,7 @@ public abstract class RegisterBlockWindow extends JPanel implements Observer { private boolean highlighting; private int highlightRow; private Register[] registers; + private boolean notMainUI = true; private static final int NAME_COLUMN = 0; private static final int NUMBER_COLUMN = 1; @@ -93,6 +94,11 @@ public RegisterBlockWindow(Register[] registers, String[] registerDescriptions, this.add(new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED)); } + public RegisterBlockWindow(Register[] registers2, String[] regtooltips, String string, String string2) { + this(registers2, regtooltips, string); + notMainUI = false; + } + protected abstract String formatRegister(Register value, int base); protected abstract void beginObserving(); @@ -203,7 +209,8 @@ public void update(Observable observable, Object obj) { // AddressCellRenderer class in DataSegmentWindow.java. this.highlighting = true; this.highlightCellForRegister((Register) observable); - Globals.getGui().getRegistersPane().setSelectedComponent(this); + if(notMainUI) + Globals.getGui().getRegistersPane().setSelectedComponent(this); } } } diff --git a/src/rars/venus/registers/RegistersWindow.java b/src/rars/venus/registers/RegistersWindow.java index 694cb4b4..eb5b5282 100644 --- a/src/rars/venus/registers/RegistersWindow.java +++ b/src/rars/venus/registers/RegistersWindow.java @@ -52,6 +52,10 @@ public RegistersWindow() { super(getRegisters(), regToolTips, "Current 32 bit value"); } + public RegistersWindow(String s){ + super(getRegisters(), regToolTips, "Current 32 bit value", "GeneralGUI"); + } + /* * A simple wrapper to add pc into the Registers array */ diff --git a/src/rars/venus/run/RunAssembleAction.java b/src/rars/venus/run/RunAssembleAction.java index 5e5bec6c..ead1eeed 100644 --- a/src/rars/venus/run/RunAssembleAction.java +++ b/src/rars/venus/run/RunAssembleAction.java @@ -1,6 +1,7 @@ package rars.venus.run; import rars.*; +import rars.Globals; import rars.riscv.hardware.*; import rars.util.FilenameFinder; import rars.util.SystemIO; @@ -11,8 +12,8 @@ import java.awt.event.ActionEvent; import java.io.File; import java.util.ArrayList; - - /* + +/* Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar Developed by Pete Sanderson (psanderson@otterbein.edu) @@ -38,7 +39,7 @@ a copy of this software and associated documentation files (the WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. (MIT license, http://www.opensource.org/licenses/mit-license.html) - */ +*/ /** * Action class for the Run -> Assemble menu item (and toolbar icon) @@ -52,13 +53,13 @@ public class RunAssembleAction extends GuiAction { private static final int LINE_LENGTH_LIMIT = 60; private VenusUI mainUI; - public RunAssembleAction(String name, Icon icon, String descrip, - Integer mnemonic, KeyStroke accel, VenusUI gui) { + public RunAssembleAction(String name, Icon icon, String descrip, Integer mnemonic, KeyStroke accel, VenusUI gui) { super(name, icon, descrip, mnemonic, accel); mainUI = gui; } - // These are both used by RunResetAction to re-assemble under identical conditions. + // These are both used by RunResetAction to re-assemble under identical + // conditions. public static ArrayList getProgramsToAssemble() { return programsToAssemble; } @@ -76,6 +77,7 @@ public void actionPerformed(ActionEvent e) { MessagesPane messagesPane = mainUI.getMessagesPane(); ExecutePane executePane = mainUI.getMainPane().getExecutePane(); RegistersPane registersPane = mainUI.getRegistersPane(); + extendedAssemblerEnabled = Globals.getSettings().getBooleanSetting(Settings.Bool.EXTENDED_ASSEMBLER_ENABLED); warningsAreErrors = Globals.getSettings().getBooleanSetting(Settings.Bool.WARNINGS_ARE_ERRORS); if (FileStatus.getFile() != null) { @@ -85,9 +87,10 @@ public void actionPerformed(ActionEvent e) { try { Globals.program = new RISCVprogram(); ArrayList filesToAssemble; - if (Globals.getSettings().getBooleanSetting(Settings.Bool.ASSEMBLE_ALL)) {// setting calls for multiple file assembly - filesToAssemble = FilenameFinder.getFilenameList( - new File(FileStatus.getName()).getParent(), Globals.fileExtensions); + if (Globals.getSettings().getBooleanSetting(Settings.Bool.ASSEMBLE_ALL)) {// setting calls for multiple + // file assembly + filesToAssemble = FilenameFinder.getFilenameList(new File(FileStatus.getName()).getParent(), + Globals.fileExtensions); } else { filesToAssemble = new ArrayList<>(); filesToAssemble.add(FileStatus.getName()); @@ -102,12 +105,13 @@ public void actionPerformed(ActionEvent e) { } } String exceptionHandler = null; - if (Globals.getSettings().getBooleanSetting(Settings.Bool.EXCEPTION_HANDLER_ENABLED) && - Globals.getSettings().getExceptionHandler() != null && - Globals.getSettings().getExceptionHandler().length() > 0) { + if (Globals.getSettings().getBooleanSetting(Settings.Bool.EXCEPTION_HANDLER_ENABLED) + && Globals.getSettings().getExceptionHandler() != null + && Globals.getSettings().getExceptionHandler().length() > 0) { exceptionHandler = Globals.getSettings().getExceptionHandler(); } - programsToAssemble = Globals.program.prepareFilesForAssembly(filesToAssemble, FileStatus.getFile().getPath(), exceptionHandler); + programsToAssemble = Globals.program.prepareFilesForAssembly(filesToAssemble, + FileStatus.getFile().getPath(), exceptionHandler); messagesPane.postMessage(buildFileNameList(name + ": assembling ", programsToAssemble)); // added logic to receive any warnings and output them.... DPS 11/28/06 ErrorList warnings = Globals.program.assemble(programsToAssemble, extendedAssemblerEnabled, @@ -115,16 +119,15 @@ public void actionPerformed(ActionEvent e) { if (warnings.warningsOccurred()) { messagesPane.postMessage(warnings.generateWarningReport()); } - messagesPane.postMessage( - name + ": operation completed successfully.\n\n"); + messagesPane.postMessage(name + ": operation completed successfully.\n\n"); FileStatus.setAssembled(true); FileStatus.set(FileStatus.RUNNABLE); - + //TODO RegisterFile.resetRegisters(); FloatingPointRegisterFile.resetRegisters(); ControlAndStatusRegisterFile.resetRegisters(); InterruptController.reset(); - + Globals.reservationTables.reset(); executePane.getTextSegmentWindow().setupTable(); executePane.getDataSegmentWindow().setupTable(); executePane.getDataSegmentWindow().highlightCellForAddress(Memory.dataBaseAddress); @@ -140,29 +143,34 @@ public void actionPerformed(ActionEvent e) { mainUI.getMainPane().setSelectedComponent(executePane); // Aug. 24, 2005 Ken Vollmar - SystemIO.resetFiles(); // Ensure that I/O "file descriptors" are initialized for a new program run + SystemIO.resetFiles(); // Ensure that I/O "file descriptors" are initialized for a new program run } catch (AssemblyException pe) { String errorReport = pe.errors().generateErrorAndWarningReport(); messagesPane.postMessage(errorReport); - messagesPane.postMessage( - name + ": operation completed with errors.\n\n"); + messagesPane.postMessage(name + ": operation completed with errors.\n\n"); // Select editor line containing first error, and corresponding error message. ArrayList errorMessages = pe.errors().getErrorMessages(); for (ErrorMessage em : errorMessages) { - // No line or position may mean File Not Found (e.g. exception file). Don't try to open. DPS 3-Oct-2010 + // No line or position may mean File Not Found (e.g. exception file). Don't try + // to open. DPS 3-Oct-2010 if (em.getLine() == 0 && em.getPosition() == 0) { continue; } if (!em.isWarning() || warningsAreErrors) { - Globals.getGui().getMessagesPane().selectErrorMessage(em.getFilename(), em.getLine(), em.getPosition()); - // Bug workaround: Line selection does not work correctly for the JEditTextArea editor - // when the file is opened then automatically assembled (assemble-on-open setting). + Globals.getGui().getMessagesPane().selectErrorMessage(em.getFilename(), em.getLine(), + em.getPosition()); + // Bug workaround: Line selection does not work correctly for the JEditTextArea + // editor + // when the file is opened then automatically assembled (assemble-on-open + // setting). // Automatic assemble happens in EditTabbedPane's openFile() method, by invoking - // this method (actionPerformed) explicitly with null argument. Thus e!=null test. + // this method (actionPerformed) explicitly with null argument. Thus e!=null + // test. // DPS 9-Aug-2010 if (e != null) { - Globals.getGui().getMessagesPane().selectEditorTextLine(em.getFilename(), em.getLine(), em.getPosition()); + Globals.getGui().getMessagesPane().selectEditorTextLine(em.getFilename(), em.getLine(), + em.getPosition()); } break; } diff --git a/src/rars/venus/run/RunGoAction.java b/src/rars/venus/run/RunGoAction.java index d4c152dc..218a3df3 100644 --- a/src/rars/venus/run/RunGoAction.java +++ b/src/rars/venus/run/RunGoAction.java @@ -16,6 +16,7 @@ import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; +import java.util.ArrayList; import java.util.Observable; import java.util.Observer; @@ -77,7 +78,6 @@ public void actionPerformed(ActionEvent e) { if (mainUI.getReset() || mainUI.getStarted()) { mainUI.setStarted(true); // added 8/27/05 - mainUI.getMessagesPane().postMessage( name + ": running " + FileStatus.getFile().getName() + "\n\n"); mainUI.getMessagesPane().selectRunMessageTab(); @@ -163,6 +163,7 @@ public void stopped(SimulationException pe, Simulator.Reason reason) { SystemIO.resetFiles(); // close any files opened in MIPS program // Bring CSRs to the front if terminated due to exception. if (pe != null) { + mainUI.getRegistersPane().setSelectedComponent(executePane.getControlAndStatusWindow()); executePane.getTextSegmentWindow().setCodeHighlighting(true); executePane.getTextSegmentWindow().unhighlightAllSteps(); @@ -229,4 +230,4 @@ private void processProgramArgumentsIfAny() { } -} \ No newline at end of file +} diff --git a/src/rars/venus/run/RunStepAction.java b/src/rars/venus/run/RunStepAction.java index 96b86bae..bbc2faf0 100644 --- a/src/rars/venus/run/RunStepAction.java +++ b/src/rars/venus/run/RunStepAction.java @@ -15,6 +15,7 @@ import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; +import java.util.ArrayList; import java.util.Observable; import java.util.Observer; @@ -101,6 +102,7 @@ public void stepped(boolean done, Simulator.Reason reason, SimulationException p executePane.getFloatingPointWindow().updateRegisters(); executePane.getControlAndStatusWindow().updateRegisters(); executePane.getDataSegmentWindow().updateValues(); + if (!done) { executePane.getTextSegmentWindow().highlightStepAtPC(); FileStatus.set(FileStatus.RUNNABLE); @@ -148,4 +150,4 @@ private void processProgramArgumentsIfAny() { } new ProgramArgumentList(programArguments).storeProgramArguments(); } -} \ No newline at end of file +} diff --git a/test/riscv-tests-64/amoaddd.s b/test/riscv-tests-64/amoaddd.s new file mode 100644 index 00000000..bb6f25ab --- /dev/null +++ b/test/riscv-tests-64/amoaddd.s @@ -0,0 +1,53 @@ +.data +.align 3 +amo_operand: .dword 0 + +.text +main: + #------------------------------------------------------------- + # Atomic tests + #------------------------------------------------------------- + +test_2: + li a0, 0xffffffff80000000 + li a1, 0xfffffffffffff800 + la a3, amo_operand + sd a0, 0(a3) + amoadd.d a4, a1, (a3) + li t2, 0xffffffff80000000 + li gp, 2 + bne a4, t2, fail + +test_3: + ld a5, 0(a3) + li t2, 0xffffffff7ffff800 + li gp, 3 + bne a5, t2, fail + +test_4: + amoadd.d a4, a1, (a3) + li t2, 0xffffffff7ffff800 + li gp, 4 + bne a4, t2, fail + +test_5: + ld a5, 0(a3) + li t2, 0xffffffff7ffff000 + li gp, 5 + bne a5, t2, fail + bne zero, gp, pass + +fail: + fence 1, 1 + slli gp, gp, 0x1 + ori gp, gp, 1 + li a7, 93 + mv a0, gp + ecall + +pass: + fence 1, 1 + li gp, 1 + li a7, 93 + li a0, 42 + ecall diff --git a/test/riscv-tests-64/amoandd.s b/test/riscv-tests-64/amoandd.s new file mode 100644 index 00000000..b5182ce7 --- /dev/null +++ b/test/riscv-tests-64/amoandd.s @@ -0,0 +1,54 @@ +.data +.align 3 +amo_operand: .dword 0 + +.text +main: + #------------------------------------------------------------- + # Atomic tests + #------------------------------------------------------------- + +test_2: + li a0, 0xffffffff80000000 + li a1, 0xfffffffffffff800 + la a3, amo_operand + sd a0, 0(a3) + amoand.d a4, a1, (a3) + li t2, 0xffffffff80000000 + li gp, 2 + bne a4, t2, fail + +test_3: + ld a5, 0(a3) + li t2, 0xffffffff80000000 + li gp, 3 + bne a5, t2, fail + +test_4: + li a1, 0x0000000080000000 + amoand.d a4, a1, (a3) + li t2, 0xffffffff80000000 + li gp, 4 + bne a4, t2, fail + +test_5: + ld a5, 0(a3) + li t2, 0x0000000080000000 + li gp, 5 + bne a5, t2, fail + bne zero, gp, pass + +fail: + fence 1, 1 + slli gp, gp, 0x1 + ori gp, gp, 1 + li a7, 93 + mv a0, gp + ecall + +pass: + fence 1, 1 + li gp, 1 + li a7, 93 + li a0, 42 + ecall diff --git a/test/riscv-tests-64/amomaxd.s b/test/riscv-tests-64/amomaxd.s new file mode 100644 index 00000000..8ff48a4f --- /dev/null +++ b/test/riscv-tests-64/amomaxd.s @@ -0,0 +1,55 @@ +.data +.align 3 +amo_operand: .dword 0 + +.text +main: + #------------------------------------------------------------- + # Atomic tests + #------------------------------------------------------------- + +test_2: + li a0, 0xffffffff80000000 + li a1, 0xfffffffffffff800 + la a3, amo_operand + sd a0, 0(a3) + amomax.d a4, a1, (a3) + li t2, 0xffffffff80000000 + li gp, 2 + bne a4, t2, fail + +test_3: + ld a5, 0(a3) + li t2, 0xfffffffffffff800 + li gp, 3 + bne a5, t2, fail + +test_4: + li a1, 1 + sd x0, 0(a3) + amomax.d a4, a1, (a3) + li t2, 0 + li gp, 4 + bne a4, t2, fail + +test_5: + ld a5, 0(a3) + li t2, 1 + li gp, 5 + bne a5, t2, fail + bne zero, gp, pass + +fail: + fence 1, 1 + slli gp, gp, 0x1 + ori gp, gp, 1 + li a7, 93 + mv a0, gp + ecall + +pass: + fence 1, 1 + li gp, 1 + li a7, 93 + li a0, 42 + ecall diff --git a/test/riscv-tests-64/amomaxud.s b/test/riscv-tests-64/amomaxud.s new file mode 100644 index 00000000..a8a3281c --- /dev/null +++ b/test/riscv-tests-64/amomaxud.s @@ -0,0 +1,55 @@ +.data +.align 3 +amo_operand: .dword 0 + +.text +main: + #------------------------------------------------------------- + # Atomic tests + #------------------------------------------------------------- + +test_2: + li a0, 0xffffffff80000000 + li a1, 0xfffffffffffff800 + la a3, amo_operand + sd a0, 0(a3) + amomaxu.d a4, a1, (a3) + li t2, 0xffffffff80000000 + li gp, 2 + bne a4, t2, fail + +test_3: + ld a5, 0(a3) + li t2, 0xfffffffffffff800 + li gp, 3 + bne a5, t2, fail + +test_4: + li a1, 0xffffffffffffffff + sd x0, 0(a3) + amomaxu.d a4, a1, (a3) + li t2, 0 + li gp, 4 + bne a4, t2, fail + +test_5: + ld a5, 0(a3) + li t2, 0xffffffffffffffff + li gp, 5 + bne a5, t2, fail + bne zero, gp, pass + +fail: + fence 1, 1 + slli gp, gp, 0x1 + ori gp, gp, 1 + li a7, 93 + mv a0, gp + ecall + +pass: + fence 1, 1 + li gp, 1 + li a7, 93 + li a0, 42 + ecall diff --git a/test/riscv-tests-64/amomind.s b/test/riscv-tests-64/amomind.s new file mode 100644 index 00000000..142aa1ff --- /dev/null +++ b/test/riscv-tests-64/amomind.s @@ -0,0 +1,55 @@ +.data +.align 3 +amo_operand: .dword 0 + +.text +main: + #------------------------------------------------------------- + # Atomic tests + #------------------------------------------------------------- + +test_2: + li a0, 0xffffffff80000000 + li a1, 0xfffffffffffff800 + la a3, amo_operand + sd a0, 0(a3) + amomin.d a4, a1, (a3) + li t2, 0xffffffff80000000 + li gp, 2 + bne a4, t2, fail + +test_3: + ld a5, 0(a3) + li t2, 0xffffffff80000000 + li gp, 3 + bne a5, t2, fail + +test_4: + li a1, 0xffffffffffffffff + sd x0, 0(a3) + amomin.d a4, a1, (a3) + li t2, 0 + li gp, 4 + bne a4, t2, fail + +test_5: + ld a5, 0(a3) + li t2, 0xffffffffffffffff + li gp, 5 + bne a5, t2, fail + bne zero, gp, pass + +fail: + fence 1, 1 + slli gp, gp, 0x1 + ori gp, gp, 1 + li a7, 93 + mv a0, gp + ecall + +pass: + fence 1, 1 + li gp, 1 + li a7, 93 + li a0, 42 + ecall diff --git a/test/riscv-tests-64/amominud.s b/test/riscv-tests-64/amominud.s new file mode 100644 index 00000000..59e674b8 --- /dev/null +++ b/test/riscv-tests-64/amominud.s @@ -0,0 +1,55 @@ +.data +.align 3 +amo_operand: .dword 0 + +.text +main: + #------------------------------------------------------------- + # Atomic tests + #------------------------------------------------------------- + +test_2: + li a0, 0xffffffff80000000 + li a1, 0xfffffffffffff800 + la a3, amo_operand + sd a0, 0(a3) + amominu.d a4, a1, (a3) + li t2, 0xffffffff80000000 + li gp, 2 + bne a4, t2, fail + +test_3: + ld a5, 0(a3) + li t2, 0xffffffff80000000 + li gp, 3 + bne a5, t2, fail + +test_4: + li a1, 0xffffffffffffffff + sd x0, 0(a3) + amominu.d a4, a1, (a3) + li t2, 0 + li gp, 4 + bne a4, t2, fail + +test_5: + ld a5, 0(a3) + li t2, 0 + li gp, 5 + bne a5, t2, fail + bne zero, gp, pass + +fail: + fence 1, 1 + slli gp, gp, 0x1 + ori gp, gp, 1 + li a7, 93 + mv a0, gp + ecall + +pass: + fence 1, 1 + li gp, 1 + li a7, 93 + li a0, 42 + ecall diff --git a/test/riscv-tests-64/amoord.s b/test/riscv-tests-64/amoord.s new file mode 100644 index 00000000..cc376e46 --- /dev/null +++ b/test/riscv-tests-64/amoord.s @@ -0,0 +1,54 @@ +.data +.align 3 +amo_operand: .dword 0 + +.text +main: + #------------------------------------------------------------- + # Atomic tests + #------------------------------------------------------------- + +test_2: + li a0, 0xffffffff80000000 + li a1, 0xfffffffffffff800 + la a3, amo_operand + sd a0, 0(a3) + amoor.d a4, a1, (a3) + li t2, 0xffffffff80000000 + li gp, 2 + bne a4, t2, fail + +test_3: + ld a5, 0(a3) + li t2, 0xfffffffffffff800 + li gp, 3 + bne a5, t2, fail + +test_4: + li a1, 1 + amoor.d a4, a1, (a3) + li t2, 0xfffffffffffff800 + li gp, 4 + bne a4, t2, fail + +test_5: + ld a5, 0(a3) + li t2, 0xfffffffffffff801 + li gp, 5 + bne a5, t2, fail + bne zero, gp, pass + +fail: + fence 1, 1 + slli gp, gp, 0x1 + ori gp, gp, 1 + li a7, 93 + mv a0, gp + ecall + +pass: + fence 1, 1 + li gp, 1 + li a7, 93 + li a0, 42 + ecall diff --git a/test/riscv-tests-64/amoswapd.s b/test/riscv-tests-64/amoswapd.s new file mode 100644 index 00000000..d6060d99 --- /dev/null +++ b/test/riscv-tests-64/amoswapd.s @@ -0,0 +1,54 @@ +.data +.align 3 +amo_operand: .dword 0 + +.text +main: + #------------------------------------------------------------- + # Atomic tests + #------------------------------------------------------------- + +test_2: + li a0, 0xffffffff80000000 + li a1, 0xfffffffffffff800 + la a3, amo_operand + sd a0, 0(a3) + amoswap.d a4, a1, (a3) + li t2, 0xffffffff80000000 + li gp, 2 + bne a4, t2, fail + +test_3: + ld a5, 0(a3) + li t2, 0xfffffffffffff800 + li gp, 3 + bne a5, t2, fail + +test_4: + li a1, 0x0000000080000000 + amoswap.d a4, a1, (a3) + li t2, 0xfffffffffffff800 + li gp, 4 + bne a4, t2, fail + +test_5: + ld a5, 0(a3) + li t2, 0x0000000080000000 + li gp, 5 + bne a5, t2, fail + bne zero, gp, pass + +fail: + fence 1, 1 + slli gp, gp, 0x1 + ori gp, gp, 1 + li a7, 93 + mv a0, gp + ecall + +pass: + fence 1, 1 + li gp, 1 + li a7, 93 + li a0, 42 + ecall diff --git a/test/riscv-tests-64/amoxord.s b/test/riscv-tests-64/amoxord.s new file mode 100644 index 00000000..6dfc27d2 --- /dev/null +++ b/test/riscv-tests-64/amoxord.s @@ -0,0 +1,54 @@ +.data +.align 3 +amo_operand: .dword 0 + +.text +main: + #------------------------------------------------------------- + # Atomic tests + #------------------------------------------------------------- + +test_2: + li a0, 0xffffffff80000000 + li a1, 0xfffffffffffff800 + la a3, amo_operand + sd a0, 0(a3) + amoxor.d a4, a1, (a3) + li t2, 0xffffffff80000000 + li gp, 2 + bne a4, t2, fail + +test_3: + ld a5, 0(a3) + li t2, 0x000000007ffff800 + li gp, 3 + bne a5, t2, fail + +test_4: + li a1, 1 + amoxor.d a4, a1, (a3) + li t2, 0x000000007ffff800 + li gp, 4 + bne a4, t2, fail + +test_5: + ld a5, 0(a3) + li t2, 0x000000007ffff801 + li gp, 5 + bne a5, t2, fail + bne zero, gp, pass + +fail: + fence 1, 1 + slli gp, gp, 0x1 + ori gp, gp, 1 + li a7, 93 + mv a0, gp + ecall + +pass: + fence 1, 1 + li gp, 1 + li a7, 93 + li a0, 42 + ecall diff --git a/test/riscv-tests/amoaddw.s b/test/riscv-tests/amoaddw.s new file mode 100644 index 00000000..4bafdd15 --- /dev/null +++ b/test/riscv-tests/amoaddw.s @@ -0,0 +1,55 @@ +.data +.align 3 +amo_operand: .dword 0 + +.text +main: + #------------------------------------------------------------- + # Atomic tests + #------------------------------------------------------------- + +test_2: + li a0, 0xffffffff80000000 + li a1, 0xfffffffffffff800 + la a3, amo_operand + sw a0, 0(a3) + amoadd.w a4, a1, (a3) + li t2, 0xffffffff80000000 + li gp, 2 + bne a4, t2, fail + +test_3: + lw a5, 0(a3) + li t2, 0x000000007ffff800 + li gp, 3 + bne a5, t2, fail + +test_4: + lui a1, 0x80000 + amoadd.w a4, a1, (a3) + lui t2, 0x80000 + addi t2, t2, -2048 + li gp, 4 + bne a4, t2, fail + +test_5: + lw a5, 0(a3) + li t2, -2048 + li gp, 5 + bne a5, t2, fail + bne zero, gp, pass + +fail: + fence 1, 1 + slli gp, gp, 0x1 + ori gp, gp, 1 + li a7, 93 + mv a0, gp + ecall + +pass: + fence 1, 1 + li gp, 1 + li a7, 93 + li a0, 42 + ecall diff --git a/test/riscv-tests/amoandw.s b/test/riscv-tests/amoandw.s new file mode 100644 index 00000000..3ec5def6 --- /dev/null +++ b/test/riscv-tests/amoandw.s @@ -0,0 +1,54 @@ +.data +.align 3 +amo_operand: .dword 0 + +.text +main: + #------------------------------------------------------------- + # Atomic tests + #------------------------------------------------------------- + +test_2: + li a0, 0xffffffff80000000 + li a1, 0xfffffffffffff800 + la a3, amo_operand + sw a0, 0(a3) + amoand.w a4, a1, (a3) + li t2, 0xffffffff80000000 + li gp, 2 + bne a4, t2, fail + +test_3: + lw a5, 0(a3) + li t2, 0xffffffff80000000 + li gp, 3 + bne a5, t2, fail + +test_4: + li a1, 0x80000000 + amoand.w a4, a1, (a3) + li t2, 0xffffffff80000000 + li gp, 4 + bne a4, t2, fail + +test_5: + lw a5, 0(a3) + li t2, 0xffffffff80000000 + li gp, 5 + bne a5, t2, fail + bne zero, gp, pass + +fail: + fence 1, 1 + slli gp, gp, 0x1 + ori gp, gp, 1 + li a7, 93 + mv a0, gp + ecall + +pass: + fence 1, 1 + li gp, 1 + li a7, 93 + li a0, 42 + ecall diff --git a/test/riscv-tests/amomaxuw.s b/test/riscv-tests/amomaxuw.s new file mode 100644 index 00000000..d0df56e2 --- /dev/null +++ b/test/riscv-tests/amomaxuw.s @@ -0,0 +1,55 @@ +.data +.align 3 +amo_operand: .dword 0 + +.text +main: + #------------------------------------------------------------- + # Atomic tests + #------------------------------------------------------------- + +test_2: + li a0, 0xffffffff80000000 + li a1, 0xfffffffffffff800 + la a3, amo_operand + sw a0, 0(a3) + amomaxu.w a4, a1, (a3) + li t2, 0xffffffff80000000 + li gp, 2 + bne a4, t2, fail + +test_3: + lw a5, 0(a3) + li t2, 0xfffffffffffff800 + li gp, 3 + bne a5, t2, fail + +test_4: + li a1, 0xffffffffffffffff + sw zero, 0(a3) + amomaxu.w a4, a1, (a3) + li t2, 0 + li gp, 4 + bne a4, t2, fail + +test_5: + lw a5, 0(a3) + li t2, 0xffffffffffffffff + li gp, 5 + bne a5, t2, fail + bne zero, gp, pass + +fail: + fence 1, 1 + slli gp, gp, 0x1 + ori gp, gp, 1 + li a7, 93 + mv a0, gp + ecall + +pass: + fence 1, 1 + li gp, 1 + li a7, 93 + li a0, 42 + ecall diff --git a/test/riscv-tests/amomaxw.s b/test/riscv-tests/amomaxw.s new file mode 100644 index 00000000..5761a67d --- /dev/null +++ b/test/riscv-tests/amomaxw.s @@ -0,0 +1,55 @@ +.data +.align 3 +amo_operand: .dword 0 + +.text +main: + #------------------------------------------------------------- + # Atomic tests + #------------------------------------------------------------- + +test_2: + li a0, 0xffffffff80000000 + li a1, 0xfffffffffffff800 + la a3, amo_operand + sw a0, 0(a3) + amomax.w a4, a1, (a3) + li t2, 0xffffffff80000000 + li gp, 2 + bne a4, t2, fail + +test_3: + lw a5, 0(a3) + li t2, 0xfffffffffffff800 + li gp, 3 + bne a5, t2, fail + +test_4: + li a1, 1 + sw zero, 0(a3) + amomax.w a4, a1, (a3) + li t2, 0 + li gp, 4 + bne a4, t2, fail + +test_5: + lw a5, 0(a3) + li t2, 1 + li gp, 5 + bne a5, t2, fail + bne zero, gp, pass + +fail: + fence 1, 1 + slli gp, gp, 0x1 + ori gp, gp, 1 + li a7, 93 + mv a0, gp + ecall + +pass: + fence 1, 1 + li gp, 1 + li a7, 93 + li a0, 42 + ecall diff --git a/test/riscv-tests/amominuw.s b/test/riscv-tests/amominuw.s new file mode 100644 index 00000000..fdadf1a6 --- /dev/null +++ b/test/riscv-tests/amominuw.s @@ -0,0 +1,55 @@ +.data +.align 3 +amo_operand: .dword 0 + +.text +main: + #------------------------------------------------------------- + # Atomic tests + #------------------------------------------------------------- + +test_2: + li a0, 0xffffffff80000000 + li a1, 0xfffffffffffff800 + la a3, amo_operand + sw a0, 0(a3) + amominu.w a4, a1, (a3) + li t2, 0xffffffff80000000 + li gp, 2 + bne a4, t2, fail + +test_3: + lw a5, 0(a3) + li t2, 0xffffffff80000000 + li gp, 3 + bne a5, t2, fail + +test_4: + li a1, 0xffffffffffffffff + sw zero, 0(a3) + amominu.w a4, a1, (a3) + li t2, 0 + li gp, 4 + bne a4, t2, fail + +test_5: + lw a5, 0(a3) + li t2, 0 + li gp, 5 + bne a5, t2, fail + bne zero, gp, pass + +fail: + fence 1, 1 + slli gp, gp, 0x1 + ori gp, gp, 1 + li a7, 93 + mv a0, gp + ecall + +pass: + fence 1, 1 + li gp, 1 + li a7, 93 + li a0, 42 + ecall diff --git a/test/riscv-tests/amominw.s b/test/riscv-tests/amominw.s new file mode 100644 index 00000000..82f786a1 --- /dev/null +++ b/test/riscv-tests/amominw.s @@ -0,0 +1,55 @@ +.data +.align 3 +amo_operand: .dword 0 + +.text +main: + #------------------------------------------------------------- + # Atomic tests + #------------------------------------------------------------- + +test_2: + li a0, 0xffffffff80000000 + li a1, 0xfffffffffffff800 + la a3, amo_operand + sw a0, 0(a3) + amomin.w a4, a1, (a3) + li t2, 0xffffffff80000000 + li gp, 2 + bne a4, t2, fail + +test_3: + lw a5, 0(a3) + li t2, 0xffffffff80000000 + li gp, 3 + bne a5, t2, fail + +test_4: + li a1, 0xffffffffffffffff + sw zero, 0(a3) + amomin.w a4, a1, (a3) + li t2, 0 + li gp, 4 + bne a4, t2, fail + +test_5: + lw a5, 0(a3) + li t2, 0xffffffffffffffff + li gp, 5 + bne a5, t2, fail + bne zero, gp, pass + +fail: + fence 1, 1 + slli gp, gp, 0x1 + ori gp, gp, 1 + li a7, 93 + mv a0, gp + ecall + +pass: + fence 1, 1 + li gp, 1 + li a7, 93 + li a0, 42 + ecall diff --git a/test/riscv-tests/amoorw.s b/test/riscv-tests/amoorw.s new file mode 100644 index 00000000..8d8e0951 --- /dev/null +++ b/test/riscv-tests/amoorw.s @@ -0,0 +1,54 @@ +.data +.align 3 +amo_operand: .dword 0 + +.text +main: + #------------------------------------------------------------- + # Atomic tests + #------------------------------------------------------------- + +test_2: + li a0, 0xffffffff80000000 + li a1, 0xfffffffffffff800 + la a3, amo_operand + sw a0, 0(a3) + amoor.w a4, a1, (a3) + li t2, 0xffffffff80000000 + li gp, 2 + bne a4, t2, fail + +test_3: + lw a5, 0(a3) + li t2, 0xfffffffffffff800 + li gp, 3 + bne a5, t2, fail + +test_4: + li a1, 1 + amoor.w a4, a1, (a3) + li t2, 0xfffffffffffff800 + li gp, 4 + bne a4, t2, fail + +test_5: + lw a5, 0(a3) + li t2, 0xfffffffffffff801 + li gp, 5 + bne a5, t2, fail + bne zero, gp, pass + +fail: + fence 1, 1 + slli gp, gp, 0x1 + ori gp, gp, 1 + li a7, 93 + mv a0, gp + ecall + +pass: + fence 1, 1 + li gp, 1 + li a7, 93 + li a0, 42 + ecall diff --git a/test/riscv-tests/amoswapw.s b/test/riscv-tests/amoswapw.s new file mode 100644 index 00000000..8afbd968 --- /dev/null +++ b/test/riscv-tests/amoswapw.s @@ -0,0 +1,54 @@ +.data +.align 3 +amo_operand: .dword 0 + +.text +main: + #------------------------------------------------------------- + # Atomic tests + #------------------------------------------------------------- + +test_2: + li a0, 0xffffffff80000000 + li a1, 0xfffffffffffff800 + la a3, amo_operand + sw a0, 0(a3) + amoswap.w a4, a1, (a3) + li t2, 0xffffffff80000000 + li gp, 2 + bne a4, t2, fail + +test_3: + lw a5, 0(a3) + li t2, 0xfffffffffffff800 + li gp, 3 + bne a5, t2, fail + +test_4: + li a1, 0x80000000 + amoswap.w a4, a1, (a3) + li t2, 0xfffffffffffff800 + li gp, 4 + bne a4, t2, fail + +test_5: + lw a5, 0(a3) + li t2, 0xffffffff80000000 + li gp, 5 + bne a5, t2, fail + bne zero, gp, pass + +fail: + fence 1, 1 + slli gp, gp, 0x1 + ori gp, gp, 1 + li a7, 93 + mv a0, gp + ecall + +pass: + fence 1, 1 + li gp, 1 + li a7, 93 + li a0, 42 + ecall diff --git a/test/riscv-tests/amoxorw.s b/test/riscv-tests/amoxorw.s new file mode 100644 index 00000000..8078f06b --- /dev/null +++ b/test/riscv-tests/amoxorw.s @@ -0,0 +1,54 @@ +.data +.align 3 +amo_operand: .dword 0 + +.text +main: + #------------------------------------------------------------- + # Atomic tests + #------------------------------------------------------------- + +test_2: + li a0, 0xffffffff80000000 + li a1, 0xfffffffffffff800 + la a3, amo_operand + sw a0, 0(a3) + amoxor.w a4, a1, (a3) + li t2, 0xffffffff80000000 + li gp, 2 + bne a4, t2, fail + +test_3: + lw a5, 0(a3) + li t2, 0x7ffff800 + li gp, 3 + bne a5, t2, fail + +test_4: + li a1, 0xc0000001 + amoxor.w a4, a1, (a3) + li t2, 0x7ffff800 + li gp, 4 + bne a4, t2, fail + +test_5: + lw a5, 0(a3) + li t2, 0xffffffffbffff801 + li gp, 5 + bne a5, t2, fail + bne zero, gp, pass + +fail: + fence 1, 1 + slli gp, gp, 0x1 + ori gp, gp, 1 + li a7, 93 + mv a0, gp + ecall + +pass: + fence 1, 1 + li gp, 1 + li a7, 93 + li a0, 42 + ecall diff --git a/test/riscv-tests/lrsc.s b/test/riscv-tests/lrsc.s new file mode 100644 index 00000000..029af77b --- /dev/null +++ b/test/riscv-tests/lrsc.s @@ -0,0 +1,93 @@ +.data +coreid: .word 0 +barrier: .word 0 +foo: .word 0 + +.text +main: + #------------------------------------------------------------- + # Atomic tests + #------------------------------------------------------------- + +# get a unique core id +la a0, coreid +li a1, 1 +amoadd.w a2, a1, (a0) + +# for now, only run this on core 0 +lbl_1: +li a3, 1 +bgeu a2, a3, lbl_1 + +lbl_2: +lw a1, (a0) +bltu a1, a3, lbl_2 + +test_2: + la a0, foo + li a5, 0xdeadbeef + sc.w a4, a5, (a0) + li t2, 1 + li gp, 2 + bne a4, t2, fail + +test_3: + lw a4, foo + li t2, 0 + li gp, 3 + bne a4, t2, fail + +# have each core add its coreid+1 to foo 128 times +la a0, foo +li a1, 0x80 +addi a2, a2, 1 +lbl_3: lr.w a4, (a0) +add a4, a4, a2 +sc.w a4, a4, (a0) +bnez a4, lbl_3 +addi a1, a1, -1 +bnez a1, lbl_3 + +# wait for all cores to finish +la a0, barrier +li a1, 1 +amoadd.w x0, a1, (a0) +lbl_4: lw a1, (a0) +blt a1, a3, lbl_4 +fence 1, 1 + +test_5: + lw a0, foo + slli a1, a3, 6 + lbl_5: sub a0, a0, a1 + addi a3, a3, -1 + bgez a3, lbl_5 + li t2, 0 + li gp, 5 + bne a0, t2, fail + +test_6: + la a0, foo + lbl_6: lr.w a1, (a0) + sc.w a1, x0, (a0) + bnez a1, lbl_6 + sc.w a1, x0 (a0) + li t2, 1 + li gp, 6 + bne a1, t2, fail + +bne zero, gp, pass +fail: + fence 1, 1 + slli gp, gp, 0x1 + ori gp, gp, 1 + li a7, 93 + mv a0, gp + ecall + +pass: + fence 1, 1 + li gp, 1 + li a7, 93 + li a0, 42 + ecall