/* This file is part of JOP, the Java Optimized Processor see <http://www.jopdesign.com/> Copyright (C) 2006-2008, Martin Schoeberl (martin@jopdesign.com) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.jopdesign.timing.jamuth; import java.util.Date; import org.apache.bcel.Constants; import com.jopdesign.timing.ConsoleTable; import com.jopdesign.timing.TimingTable; import com.jopdesign.timing.ConsoleTable.Alignment; import com.jopdesign.timing.ConsoleTable.TableRow; import com.jopdesign.tools.JopInstr; /** * It has wcet info on byte code instruction granularity. Should we consider * making a class that wraps the microcodes into objects? */ public class JamuthTimingTable extends TimingTable<JamuthInstructionInfo> { private static final int WCETNOTAVAILABLE = -1; // the read and write wait states, ram_cnt - 1 public int r = 8; public int w = 5; // cache read wait state (r-1) public int c = 0; public int fcs = 1; public int fca = 4; // wait states for a read to the scratchpad public int rs = 5; // cycles to call a trap routine public int t = 15+rs; // latency cycles of a jump public int j = 4; public int fls = 0; public int fla = 4; // jamuth bytecodes (unused ?) public static final short SETHI = 237; public static final short EXTENDED = 255; public JamuthTimingTable() { // constants hardcoded for now } public boolean hasTimingInfo(int opcode) { if (getCycles(new JamuthInstructionInfo(opcode,0)) == WCETNOTAVAILABLE) return false; else return true; } /** * Returns the wcet count for the instruction. * - FIXME: is the calculation for the alignment delay correct ? * - FIXME: No branchlatency for ifeq ? * - TODO: pipeline dependencies ? * - TODO: LDC * - TODO: tableswitch, lookupswitch * - TODO: monitorenter, monitorext * - Unsupported: invokeinterface, instanceof, checkcast */ public long getCycles(JamuthInstructionInfo info) { int wcet = -1; int branchlatency=fla; // Add latency if the jump target isn't aligned // TODO @ sascha: is > 0 correct (i.e. 4 byte alignment) ? if(! info.hasJumpTargetAddress() || (info.getJumpTargetAddress() & 3) > 0) { branchlatency+=fla; } int latency = 0; switch (info.getOpcode()) { // NOP = 0 case Constants.NOP: wcet = 1; break; // ACONST_NULL = 1 case Constants.ACONST_NULL: wcet = 1; break; // ICONST_M1 = 2 case Constants.ICONST_M1: wcet = 1; break; // ICONST_0 = 3 case Constants.ICONST_0: wcet = 1; break; // ICONST_1 = 4 case Constants.ICONST_1: wcet = 1; break; // ICONST_2 = 5 case Constants.ICONST_2: wcet = 1; break; // ICONST_3 = 6 case Constants.ICONST_3: wcet = 1; break; // ICONST_4 = 7 case Constants.ICONST_4: wcet = 1; break; // ICONST_5 = 8 case Constants.ICONST_5: wcet = 1; break; // LCONST_0 = 9 case Constants.LCONST_0: wcet = 1; break; // LCONST_1 = 10 case Constants.LCONST_1: wcet = 1; break; // FCONST_0 = 11 case Constants.FCONST_0: wcet = 1; break; // FCONST_1 = 12 case Constants.FCONST_1: wcet = 2; break; // FCONST_2 = 13 case Constants.FCONST_2: wcet = 2; break; // DCONST_0 = 14 case Constants.DCONST_0: wcet = 1; break; // DCONST_1 = 15 case Constants.DCONST_1: wcet = 3; break; // BIPUSH = 16 case Constants.BIPUSH: wcet = 1; break; // SIPUSH = 17 case Constants.SIPUSH: wcet = 1; break; // LDC = 18 case Constants.LDC: // TODO: je nach dem, ob String oder Zahl wcet = -1; break; // LDC_W = 19 case Constants.LDC_W: wcet = 6 + r; latency = r; break; // LDC2_W = 20 case Constants.LDC2_W: wcet = 9+(2*r); latency = 2*r; break; // ILOAD = 21 case Constants.ILOAD: wcet = 1; break; // LLOAD = 22 case Constants.LLOAD: wcet = 1; break; // FLOAD = 23 case Constants.FLOAD: wcet = 1; break; // DLOAD = 24 case Constants.DLOAD: wcet = 1; break; // ALOAD = 25 case Constants.ALOAD: wcet = 1; break; // ILOAD_0 = 26 case Constants.ILOAD_0: wcet = 1; break; // ILOAD_1 = 27 case Constants.ILOAD_1: wcet = 1; break; // ILOAD_2 = 28 case Constants.ILOAD_2: wcet = 1; break; // ILOAD_3 = 29 case Constants.ILOAD_3: wcet = 1; break; // LLOAD_0 = 30 case Constants.LLOAD_0: wcet = 1; break; // LLOAD_1 = 31 case Constants.LLOAD_1: wcet = 1; break; // LLOAD_2 = 32 case Constants.LLOAD_2: wcet = 1; break; // LLOAD_3 = 33 case Constants.LLOAD_3: wcet = 1; break; // FLOAD_0 = 34 case Constants.FLOAD_0: wcet = 1; break; // FLOAD_1 = 35 case Constants.FLOAD_1: wcet = 1; break; // FLOAD_2 = 36 case Constants.FLOAD_2: wcet = 1; break; // FLOAD_3 = 37 case Constants.FLOAD_3: wcet = 1; break; // DLOAD_0 = 38 case Constants.DLOAD_0: wcet = 1; break; // DLOAD_1 = 39 case Constants.DLOAD_1: wcet = 1; break; // DLOAD_2 = 40 case Constants.DLOAD_2: wcet = 1; break; // DLOAD_3 = 41 case Constants.DLOAD_3: wcet = 1; break; // ALOAD_0 = 42 case Constants.ALOAD_0: wcet = 1; break; // ALOAD_1 = 43 case Constants.ALOAD_1: wcet = 1; break; // ALOAD_2 = 44 case Constants.ALOAD_2: wcet = 1; break; // ALOAD_3 = 45 case Constants.ALOAD_3: wcet = 1; break; // IALOAD = 46 case Constants.IALOAD: wcet = 4 + r; latency = r; break; // LALOAD = 47 case Constants.LALOAD: wcet = 7+(2*r); latency = 2*r; break; // FALOAD = 48 case Constants.FALOAD: wcet = 4 + r; latency = r; break; // DALOAD = 49 case Constants.DALOAD: wcet = 7+(2*r); latency = 2*r; break; // AALOAD = 50 case Constants.AALOAD: wcet = 4 + r; latency = r; break; // BALOAD = 51 case Constants.BALOAD: wcet = 4 + r; latency = r; break; // CALOAD = 52 case Constants.CALOAD: wcet = 4 + r; latency = r; break; // SALOAD = 53 case Constants.SALOAD: wcet = 4 + r; latency = r; break; // ISTORE = 54 case Constants.ISTORE: wcet = 1; break; // LSTORE = 55 case Constants.LSTORE: wcet = 1; break; // FSTORE = 56 case Constants.FSTORE: wcet = 1; break; // DSTORE = 57 case Constants.DSTORE: wcet = 1; break; // ASTORE = 58 case Constants.ASTORE: wcet = 2; break; // ISTORE_0 = 59 case Constants.ISTORE_0: wcet = 1; break; // ISTORE_1 = 60 case Constants.ISTORE_1: wcet = 1; break; // ISTORE_2 = 61 case Constants.ISTORE_2: wcet = 1; break; // ISTORE_3 = 62 case Constants.ISTORE_3: wcet = 1; break; // LSTORE_0 = 63 case Constants.LSTORE_0: wcet = 1; break; // LSTORE_1 = 64 case Constants.LSTORE_1: wcet = 1; break; // LSTORE_2 = 65 case Constants.LSTORE_2: wcet = 1; break; // LSTORE_3 = 66 case Constants.LSTORE_3: wcet = 1; break; // FSTORE_0 = 67 case Constants.FSTORE_0: wcet = 1; break; // FSTORE_1 = 68 case Constants.FSTORE_1: wcet = 1; break; // FSTORE_2 = 69 case Constants.FSTORE_2: wcet = 1; break; // FSTORE_3 = 70 case Constants.FSTORE_3: wcet = 1; break; // DSTORE_0 = 71 case Constants.DSTORE_0: wcet = 1; break; // DSTORE_1 = 72 case Constants.DSTORE_1: wcet = 1; break; // DSTORE_2 = 73 case Constants.DSTORE_2: wcet = 1; break; // DSTORE_3 = 74 case Constants.DSTORE_3: wcet = 1; break; // ASTORE_0 = 75 case Constants.ASTORE_0: wcet = 2+w; latency = w; break; // ASTORE_1 = 76 case Constants.ASTORE_1: wcet = 2+w; latency = w; break; // ASTORE_2 = 77 case Constants.ASTORE_2: wcet = 2+w; latency = w; break; // ASTORE_3 = 78 case Constants.ASTORE_3: wcet = 2+w; latency = w; break; // IASTORE = 79 case Constants.IASTORE: wcet = 7+w; latency = w; break; // LASTORE = 80 case Constants.LASTORE: wcet = 11+(2*w); latency = 2*w; break; // FASTORE = 81 case Constants.FASTORE: wcet = 7+w; latency = w; break; // DASTORE = 82 case Constants.DASTORE: wcet = 11+(2*w); latency = 2*w; break; // AASTORE = 83 case Constants.AASTORE: wcet = 8+(2*w); latency = 2*w; break; // BASTORE = 84 case Constants.BASTORE: wcet = 5+w; latency = w; break; // CASTORE = 85 case Constants.CASTORE: wcet = 7+w; latency = w; break; // SASTORE = 86 case Constants.SASTORE: wcet = 7+w; latency = w; break; // POP = 87 case Constants.POP: wcet = 1; break; // POP2 = 88 case Constants.POP2: wcet = 1; break; // DUP = 89 case Constants.DUP: wcet = 1; break; // DUP_X1 = 90 case Constants.DUP_X1: wcet = 4; break; // DUP_X2 = 91 case Constants.DUP_X2: wcet = 6; break; // DUP2 = 92 case Constants.DUP2: wcet = 1; break; // DUP2_X1 = 93 case Constants.DUP2_X1: wcet = 5; break; // DUP2_X2 = 94 case Constants.DUP2_X2: wcet = 6; break; // SWAP = 95 case Constants.SWAP: wcet = -1; //todo break; // IADD = 96 case Constants.IADD: wcet = 1; break; // LADD = 97 case Constants.LADD: wcet = -1; //todo break; // FADD = 98 case Constants.FADD: wcet = -1; //todo break; // DADD = 99 case Constants.DADD: wcet = -1; //todo break; // ISUB = 100 case Constants.ISUB: wcet = 1; break; // LSUB = 101 case Constants.LSUB: wcet = -1; //todo break; // FSUB = 102 case Constants.FSUB: wcet = -1; //todo break; // DSUB = 103 case Constants.DSUB: wcet = -1; //todo break; // IMUL = 104 case Constants.IMUL: wcet = 1; break; // LMUL = 105 case Constants.LMUL: wcet = -1; //todo break; // FMUL = 106 case Constants.FMUL: wcet = -1; // todo break; // DMUL = 107 case Constants.DMUL: wcet = -1; // todo break; // IDIV = 108 case Constants.IDIV: wcet = -1; // todo break; // LDIV = 109 case Constants.LDIV: wcet = -1; // todo break; // FDIV = 110 case Constants.FDIV: wcet = -1; // todo break; // DDIV = 111 case Constants.DDIV: wcet = -1; // todo break; // IREM = 112 case Constants.IREM: wcet = -1; // todo break; // LREM = 113 case Constants.LREM: wcet = -1; // todo break; // FREM = 114 case Constants.FREM: wcet = -1; // todo break; // DREM = 115 case Constants.DREM: wcet = -1; // todo break; // INEG = 116 case Constants.INEG: wcet = 1; break; // LNEG = 117 case Constants.LNEG: wcet = -1; // todo break; // FNEG = 118 case Constants.FNEG: wcet = -1; // todo break; // DNEG = 119 case Constants.DNEG: wcet = -1; // todo break; // ISHL = 120 case Constants.ISHL: wcet = 1; break; // LSHL = 121 case Constants.LSHL: wcet = -1; // todo break; // ISHR = 122 case Constants.ISHR: wcet = 1; break; // LSHR = 123 case Constants.LSHR: wcet = -1; // todo break; // IUSHR = 124 case Constants.IUSHR: wcet = 1; break; // LUSHR = 125 case Constants.LUSHR: wcet = -1; // todo break; // IAND = 126 case Constants.IAND: wcet = 1; break; // LAND = 127 case Constants.LAND: wcet = -1; // todo break; // IOR = 128 case Constants.IOR: wcet = 1; break; // LOR = 129 case Constants.LOR: wcet = -1; // todo break; // IXOR = 130 case Constants.IXOR: wcet = 1; break; // LXOR = 131 case Constants.LXOR: wcet = -1; // todo break; // IINC = 132 case Constants.IINC: wcet = 1; break; // I2L = 133 case Constants.I2L: wcet = -1; // todo break; // I2F = 134 case Constants.I2F: wcet = -1; // todo break; // I2D = 135 case Constants.I2D: wcet = -1; // todo break; // L2I = 136 case Constants.L2I: wcet = 1; break; // L2F = 137 case Constants.L2F: wcet = -1; // todo break; // L2D = 138 case Constants.L2D: wcet = -1; // todo break; // F2I = 139 case Constants.F2I: wcet = -1; // todo break; // F2L = 140 case Constants.F2L: wcet = -1; // todo break; // F2D = 141 case Constants.F2D: wcet = -1; // todo break; // D2I = 142 case Constants.D2I: wcet = -1; // todo break; // D2L = 143 case Constants.D2L: wcet = -1; // todo break; // D2F = 144 case Constants.D2F: wcet = -1; // todo break; // I2B = 145 case Constants.I2B: wcet = 1; break; // INT2BYTE = 145 // Old notion // case Constants.INT2BYTE : wcet = -1; break; // I2C = 146 case Constants.I2C: wcet = 1; break; // INT2CHAR = 146 // Old notion // case Constants.INT2CHAR : wcet = -1; break; // I2S = 147 case Constants.I2S: wcet = 1; break; // INT2SHORT = 147 // Old notion // case Constants.INT2SHORT : wcet = -1; break; // LCMP = 148 case Constants.LCMP: wcet = -1; // todo break; // FCMPL = 149 case Constants.FCMPL: wcet = -1; // todo break; // FCMPG = 150 case Constants.FCMPG: wcet = -1; // todo break; // DCMPL = 151 case Constants.DCMPL: wcet = -1; // todo break; // DCMPG = 152 case Constants.DCMPG: wcet = -1; // todo break; // IFEQ = 153 case Constants.IFEQ: // - FIXME: No branchlatency for ifeq ? wcet = 1+j; latency = j; break; // IFNE = 154 case Constants.IFNE: wcet = 1+branchlatency; latency = branchlatency; break; // IFLT = 155 case Constants.IFLT: wcet = 1+branchlatency; latency = branchlatency; break; // IFGE = 156 case Constants.IFGE: wcet = 1+branchlatency; latency = branchlatency; break; // IFGT = 157 case Constants.IFGT: wcet = 1+branchlatency; latency = branchlatency; break; // IFLE = 158 case Constants.IFLE: wcet = 1+branchlatency; latency = branchlatency; break; // IF_ICMPEQ = 159 case Constants.IF_ICMPEQ: wcet = 1+branchlatency; latency = branchlatency; break; // IF_ICMPNE = 160 case Constants.IF_ICMPNE: wcet = 1+branchlatency; latency = branchlatency; break; // IF_ICMPLT = 161 case Constants.IF_ICMPLT: wcet = 1+branchlatency; latency = branchlatency; break; // IF_ICMPGE = 162 case Constants.IF_ICMPGE: wcet = 1+branchlatency; latency = branchlatency; break; // IF_ICMPGT = 163 case Constants.IF_ICMPGT: wcet = 1+branchlatency; latency = branchlatency; break; // IF_ICMPLE = 164 case Constants.IF_ICMPLE: wcet = 1+branchlatency; latency = branchlatency; break; // IF_ACMPEQ = 165 case Constants.IF_ACMPEQ: wcet = 1+branchlatency; latency = branchlatency; break; // IF_ACMPNE = 166 case Constants.IF_ACMPNE: wcet = 1+branchlatency; latency = branchlatency; break; // GOTO = 167 case Constants.GOTO: wcet = 1+branchlatency; latency = branchlatency; break; // JSR = 168 case Constants.JSR: wcet = 8+branchlatency-3; latency = branchlatency-3; break; // RET = 169 case Constants.RET: wcet = 1+branchlatency; latency = branchlatency; break; // TABLESWITCH = 170 case Constants.TABLESWITCH: wcet = -1; // TODO break; // LOOKUPSWITCH = 171 case Constants.LOOKUPSWITCH: wcet = -1; // TODO break; // IRETURN = 172 case Constants.IRETURN: wcet = 7+branchlatency-6; latency = 2+branchlatency-6; break; // LRETURN = 173 case Constants.LRETURN: wcet = 9; latency = 2; break; // FRETURN = 174 case Constants.FRETURN: wcet = 7+branchlatency-6; latency = 2+branchlatency-6; break; // DRETURN = 175 case Constants.DRETURN: wcet = 9; latency = 2; break; // ARETURN = 176 case Constants.ARETURN: wcet = 10+w; latency = 2; break; // RETURN = 177 case Constants.RETURN: wcet = 6+branchlatency-6; latency = 2; break; // GETSTATIC = 178 case Constants.GETSTATIC: wcet = 1 + r; latency = r; break; // PUTSTATIC = 179 case Constants.PUTSTATIC: wcet = 4+(2*w); latency = w; break; // GETFIELD = 180 case Constants.GETFIELD: wcet = 1 + r; latency = r; break; // PUTFIELD = 181 case Constants.PUTFIELD: wcet = 5+(2*w); latency = 2*w; break; // INVOKEVIRTUAL = 182 case Constants.INVOKEVIRTUAL: wcet = 58 + 18 + (3*branchlatency) + (5*r) + t; latency = 18 + (3*branchlatency) + (5*r); break; // INVOKESPECIAL = 183 case Constants.INVOKESPECIAL: wcet = 46 + 14 + (2*branchlatency) + (5*r) + t; latency = 14 + (2*branchlatency) + (5*r); break; // INVOKENONVIRTUAL = 183 // case Constants.INVOKENONVIRTUAL : wcet = -1; break; // INVOKESTATIC = 184 case Constants.INVOKESTATIC: wcet = 46 + 14 + (2*branchlatency) + (5*r) + t; latency = 14 + (2*branchlatency) + (5*r); break; // INVOKEINTERFACE = 185 case Constants.INVOKEINTERFACE: wcet = -1; //112 + 4 * r; //TODO break; // NEW = 187 case Constants.NEW: wcet = -1; break; // NEWARRAY = 188 case Constants.NEWARRAY: wcet = -1; break; // ANEWARRAY = 189 case Constants.ANEWARRAY: wcet = -1; break; // ARRAYLENGTH = 190 case Constants.ARRAYLENGTH: wcet = 1+r; break; // ATHROW = 191 case Constants.ATHROW: wcet = -1; break; // CHECKCAST = 192 case Constants.CHECKCAST: wcet = -1; //TODO break; // INSTANCEOF = 193 case Constants.INSTANCEOF: wcet = -1; //TODO break; // MONITORENTER = 194 case Constants.MONITORENTER: wcet = -1; //TODO break; // MONITOREXIT = 195 case Constants.MONITOREXIT: wcet = -1; //TODO break; // WIDE = 196 case Constants.WIDE: wcet = -1; break; // MULTIANEWARRAY = 197 case Constants.MULTIANEWARRAY: wcet = -1; break; // IFNULL = 198 case Constants.IFNULL: wcet = 1+branchlatency; latency = branchlatency; break; // IFNONNULL = 199 case Constants.IFNONNULL: wcet = 1+j; latency = j; break; // GOTO_W = 200 case Constants.GOTO_W: wcet = -1; //TODO break; // JSR_W = 201 case Constants.JSR_W: wcet = -1; //TODO break; // JOPSYS_RD = 209 default: wcet = -1; } if(latency<0) latency=0; return wcet; } // print timing table public static void main(String[] argv) { String head = "Jamuth Timing Table on " + new Date(); System.out.println(head); System.out.println(ConsoleTable.getSepLine('=',head.length())); System.out.println(); ConsoleTable table = new ConsoleTable(); JamuthTimingTable timing = new JamuthTimingTable(); table.addLegendTop(String.format("r = %d, w = %d, c = %d, fcs = %d, fca = %d", timing.r,timing.w,timing.c,timing.fcs,timing.fca)); table.addLegendTop(String.format("rs = %d, t = %d, j = %d, fls = %d, fla = %d", timing.rs,timing.t,timing.j,timing.fls,timing.fla)); // build table table.addColumn("opcode", Alignment.ALIGN_RIGHT) .addColumn("name", Alignment.ALIGN_LEFT) .addColumn("Cyc (&jump = 4)", Alignment.ALIGN_RIGHT) .addColumn("Cyc (&jump = 1)", Alignment.ALIGN_RIGHT); for(int i = 0; i < 256; i++) { int opcode = i; if(JopInstr.isReserved(opcode)) continue; TableRow row = table.addRow(); row.addCell(opcode) .addCell(JopInstr.OPCODE_NAMES[i]); if(timing.hasTimingInfo(opcode)) { long t1 = timing.getCycles(new JamuthInstructionInfo(opcode,4)); long t2 = timing.getCycles(new JamuthInstructionInfo(opcode,1)); row.addCell(t1); row.addCell(t2); } else { row.addCell("... no info ...",2,Alignment.ALIGN_LEFT); } } System.out.println(table.render()); } }