package elw.dp.mips; import base.pattern.Result; import junit.framework.TestCase; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Arrays; import java.util.List; public class AluTest extends TestCase { protected InstructionContext iCtx; protected Memory memory; public void testAnnotations() { final Method[] aluMethods = Alu.class.getDeclaredMethods(); for (Method m : aluMethods) { if (Modifier.isStatic(m.getModifiers())) { continue; } final InstructionDesc descAnnot = m.getAnnotation(InstructionDesc.class); assertNotNull(m.getName(), descAnnot); assertEquals(m.getName(), 32, descAnnot.template().length()); assertTrue(m.getName(), descAnnot.syntax().startsWith(m.getName())); } } private MipsValidator validator; protected Registers registers; private Alu alu; public void setUp() { validator = new MipsValidator(); alu = validator.getDataPath().getAlu(); registers = validator.getDataPath().getRegisters(); memory = validator.getDataPath().getMemory(); iCtx = new InstructionContext( validator.getDataPath().getInstructions(), memory, registers ); } protected void assembleInstruction(final String instructionCode) { assembleInstructions(Arrays.asList( instructionCode, "noop", "label: noop" )); } protected void assembleInstructions(final List<String> intstructions) { final Instruction instruction = validator.assemble(new Result[1], intstructions)[0]; iCtx.setInstruction(instruction); } public void testSltu_negpos_false() { registers.setReg(Reg.t1, -1); registers.setReg(Reg.t2, 0); registers.setReg(Reg.t3, 2); assembleInstruction("sltu $t3, $t1, $t2"); alu.sltu(iCtx); assertEquals(-1, registers.getReg(Reg.t1)); assertEquals(0, registers.getReg(Reg.t2)); assertEquals(0, registers.getReg(Reg.t3)); } public void testSltu_posneg_true() { registers.setReg(Reg.t1, 0); registers.setReg(Reg.t2, -1); registers.setReg(Reg.t3, 2); assembleInstruction("sltu $t3, $t1, $t2"); alu.sltu(iCtx); assertEquals(0, registers.getReg(Reg.t1)); assertEquals(-1, registers.getReg(Reg.t2)); assertEquals(1, registers.getReg(Reg.t3)); } public void testSltu_pospos_true() { registers.setReg(Reg.t1, 0); registers.setReg(Reg.t2, 1); registers.setReg(Reg.t3, 2); assembleInstruction("sltu $t3, $t1, $t2"); alu.sltu(iCtx); assertEquals(0, registers.getReg(Reg.t1)); assertEquals(1, registers.getReg(Reg.t2)); assertEquals(1, registers.getReg(Reg.t3)); } public void testSltu_pospos_false() { registers.setReg(Reg.t1, 1); registers.setReg(Reg.t2, 0); registers.setReg(Reg.t3, 2); assembleInstruction("sltu $t3, $t1, $t2"); alu.sltu(iCtx); assertEquals(1, registers.getReg(Reg.t1)); assertEquals(0, registers.getReg(Reg.t2)); assertEquals(0, registers.getReg(Reg.t3)); } public void testSltu_negneg_false() { registers.setReg(Reg.t1, -2); registers.setReg(Reg.t2, -1); registers.setReg(Reg.t3, 2); assembleInstruction("sltu $t3, $t1, $t2"); alu.sltu(iCtx); assertEquals(-2, registers.getReg(Reg.t1)); assertEquals(-1, registers.getReg(Reg.t2)); assertEquals(1, registers.getReg(Reg.t3)); } public void testSltu_negneg_true() { registers.setReg(Reg.t1, -1); registers.setReg(Reg.t2, -2); registers.setReg(Reg.t3, 2); assembleInstruction("sltu $t3, $t1, $t2"); alu.sltu(iCtx); assertEquals(-1, registers.getReg(Reg.t1)); assertEquals(-2, registers.getReg(Reg.t2)); assertEquals(0, registers.getReg(Reg.t3)); } public void testAdd() { registers.setReg(Reg.t2, -1); registers.setReg(Reg.t3, 2); registers.setReg(Reg.t1, 18); assembleInstruction("add $t1, $t2, $t3"); alu.add(iCtx); assertEquals(-1, registers.getReg(Reg.t2)); assertEquals(2, registers.getReg(Reg.t3)); assertEquals(1, registers.getReg(Reg.t1)); } public void testAdd_forOverflow() { registers.setReg(Reg.t1, 18); registers.setReg(Reg.t2, 2); registers.setReg(Reg.t3, Integer.MAX_VALUE); assembleInstruction("add $t1, $t2, $t3"); alu.add(iCtx); assertEquals(Integer.MIN_VALUE + 1, registers.getReg(Reg.t1)); assertEquals(2, registers.getReg(Reg.t2)); assertEquals(Integer.MAX_VALUE, registers.getReg(Reg.t3)); } public void testBGEZAL_forJAL() { registers.setReg(Reg.t1, 18); assembleInstruction("bgezal $t1, label"); final int codeBase = validator.getDataPath().getInstructions().getCodeBase(); assertEquals(codeBase, registers.getReg(Reg.pc)); alu.bgezal(iCtx); assertEquals(18, registers.getReg(Reg.t1)); assertEquals(codeBase + 8, registers.getReg(Reg.pc)); assertEquals(codeBase + 4, registers.getReg(Reg.ra)); } public void testBGEZAL_forDefault() { registers.setReg(Reg.t1, -18); registers.setReg(Reg.ra, 0x123456); assembleInstruction("bgezal $t1, label"); final int codeBase = validator.getDataPath().getInstructions().getCodeBase(); assertEquals(codeBase, registers.getReg(Reg.pc)); alu.bgezal(iCtx); assertEquals(-18, registers.getReg(Reg.t1)); assertEquals(codeBase + 4, registers.getReg(Reg.pc)); assertEquals(0x123456, registers.getReg(Reg.ra)); } }