/*
This file is part of JOP, the Java Optimized Processor
see <http://www.jopdesign.com/>
Copyright (C) 2006-2008, Martin Schoeberl (martin@jopdesign.com)
Copyright (C) 2006, Rasmus Ulslev Pedersen
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.jop;
import com.jopdesign.common.misc.MiscUtils;
import com.jopdesign.tools.JopInstr;
import java.util.HashMap;
import java.util.Map;
/**
* WCETInstruction provides WCET info on byte code granularity, using a hardcoded
* lookup table. For implemented architectures, it is deprecated in favor of
* implemenations based on microcode timing analysis, {@see SingleCoreTiming}
*/
public class WCETInstruction {
// indicate that wcet is not available for this bytecode
public static final int WCETNOTAVAILABLE = -1;
// hidden load cycles
public static final int INVOKE_HIDDEN_LOAD_CYCLES = 37;
public static final int RETURN_HIDDEN_LOAD_CYCLES = 9;
public static final int ARETURN_HIDDEN_LOAD_CYCLES = 10;
public static final int FRETURN_HIDDEN_LOAD_CYCLES = 10;
public static final int IRETURN_HIDDEN_LOAD_CYCLES = 10;
public static final int LRETURN_HIDDEN_LOAD_CYCLES = 11;
public static final int DRETURN_HIDDEN_LOAD_CYCLES = 11;
public static final int MIN_HIDDEN_LOAD_CYCLES = RETURN_HIDDEN_LOAD_CYCLES;
// Default configuration
// dspio Board: r=1, w=2
// DE2 Board: r=3, w=5
public static final int DEFAULT_R = 1;
public static final int DEFAULT_W = 2;
public static int DEFAULT_CPUS = 8;
public static int DEFAULT_TIMESLOT = 10; // has to be greater r !!
// the read and write wait states, ram_cnt - 1
public int r;
public int w;
// cache read wait state (r-1)
public int c() { return r - 1; }
// CMP: Multiprocessing with time sliced memory access (christof)
public static boolean cmp = false;
// Arbitration
public int cpus = 8;
public int timeslot = 10; // has to be greater r !!
// Arbitration Array
public boolean [] arbiter;
// bh: max cycles seems unnecessary: you should check statically whether
// the configuration is valid (e.g. timeslot > delay)
public static final int MAX_CYCLES = 1000000;
public int getArbiterPeriod() { return cpus*timeslot; }
// Build Instructions
public static final int NOP = 0;
public static final int RD = 1;
public static final int WR = 2;
// Static Instruction patterns
public WCETMemInstruction ldc;
public WCETMemInstruction ldc_w;
public WCETMemInstruction ldc2_w;
public WCETMemInstruction xaload;
public WCETMemInstruction xastore;
public WCETMemInstruction getstaticx;
public WCETMemInstruction putstatic;
public WCETMemInstruction getfield;
public WCETMemInstruction putfield;
public WCETMemInstruction arraylength;
public WCETMemInstruction jopsys_rdx;
public WCETMemInstruction jopsys_wrx;
// Dynamic Instruction pattern dependent on cache
public WCETMemInstruction ireturn;
public WCETMemInstruction freturn;
public WCETMemInstruction areturn;
public WCETMemInstruction lreturn;
public WCETMemInstruction dreturn;
public WCETMemInstruction returnx; // return
public WCETMemInstruction invokevirtual;
public WCETMemInstruction invokespecial;
public WCETMemInstruction invokestatic; // same as invokespecial
public WCETMemInstruction invokeinterface;
/** Single-Core timing */
public WCETInstruction(int rws, int wws) {
configure(rws,wws);
}
/** Multi-Core timing */
public WCETInstruction(int cpus, int timeslot, int rws, int wws) {
configureCMP(cpus, timeslot, rws, wws);
}
public void configure(int rws, int wws) {
cmp = false;
r = rws;
w = wws;
}
public void configureCMP(int cpuCount, int timeslot, int rws, int wws) {
if(cpuCount < 1) throw new AssertionError("WCETInstruction: cpus < 1");
if(timeslot < r) throw new AssertionError("WCETInstruction (cmp): timeslot < r");
cmp = true;
r = rws;
w = wws;
cpus = cpuCount;
initCMP(timeslot);
}
private void initCMP(int timeslot) {
// Initialize
this.timeslot = timeslot;
initArbiter();
generateStaticInstr();
}
//Native bytecodes (see jvm.asm)
private static final int JOPSYS_INVAL = 204;
private static final int JOPSYS_RD = 209;
private static final int JOPSYS_WR = 210;
private static final int JOPSYS_RDMEM = 211;
private static final int JOPSYS_WRMEM = 212;
private static final int JOPSYS_RDINT = 213;
private static final int JOPSYS_WRINT = 214;
private static final int JOPSYS_GETSP = 215;
private static final int JOPSYS_SETSP = 216;
private static final int JOPSYS_GETVP = 217;
private static final int JOPSYS_SETVP = 218;
private static final int JOPSYS_INT2EXT = 219;
private static final int JOPSYS_EXT2INT = 220;
private static final int JOPSYS_NOP = 221;
private static final int GETSTATIC_REF = 224;
private static final int GETFIELD_REF = 226;
private static final int GETSTATIC_LONG = 228;
private static final int PUTSTATIC_LONG = 229;
private static final int GETFIELD_LONG = 230;
private static final int PUTFIELD_LONG = 231;
private static final int JOPSYS_MEMCPY = 232;
private static final int JOPSYS_GETFIELD = 233;
private static final int JOPSYS_PUTFIELD = 234;
private static final int JOPSYS_GETSTATIC = 238;
private static final int JOPSYS_PUTSTATIC = 239;
private static String ILLEGAL_OPCODE = "ILLEGAL_OPCODE";
/**
* Names of opcodes.
*/
protected static final String[] OPCODE_NAMES = { "nop", "aconst_null",
"iconst_m1", "iconst_0", "iconst_1", "iconst_2", "iconst_3",
"iconst_4", "iconst_5", "lconst_0", "lconst_1", "fconst_0",
"fconst_1", "fconst_2", "dconst_0", "dconst_1", "bipush", "sipush",
"ldc", "ldc_w", "ldc2_w", "iload", "lload", "fload", "dload",
"aload", "iload_0", "iload_1", "iload_2", "iload_3", "lload_0",
"lload_1", "lload_2", "lload_3", "fload_0", "fload_1", "fload_2",
"fload_3", "dload_0", "dload_1", "dload_2", "dload_3", "aload_0",
"aload_1", "aload_2", "aload_3", "iaload", "laload", "faload",
"daload", "aaload", "baload", "caload", "saload", "istore",
"lstore", "fstore", "dstore", "astore", "istore_0", "istore_1",
"istore_2", "istore_3", "lstore_0", "lstore_1", "lstore_2",
"lstore_3", "fstore_0", "fstore_1", "fstore_2", "fstore_3",
"dstore_0", "dstore_1", "dstore_2", "dstore_3", "astore_0",
"astore_1", "astore_2", "astore_3", "iastore", "lastore",
"fastore", "dastore", "aastore", "bastore", "castore", "sastore",
"pop", "pop2", "dup", "dup_x1", "dup_x2", "dup2", "dup2_x1",
"dup2_x2", "swap", "iadd", "ladd", "fadd", "dadd", "isub", "lsub",
"fsub", "dsub", "imul", "lmul", "fmul", "dmul", "idiv", "ldiv",
"fdiv", "ddiv", "irem", "lrem", "frem", "drem", "ineg", "lneg",
"fneg", "dneg", "ishl", "lshl", "ishr", "lshr", "iushr", "lushr",
"iand", "land", "ior", "lor", "ixor", "lxor", "iinc", "i2l", "i2f",
"i2d", "l2i", "l2f", "l2d", "f2i", "f2l", "f2d", "d2i", "d2l",
"d2f", "i2b", "i2c", "i2s", "lcmp", "fcmpl", "fcmpg", "dcmpl",
"dcmpg", "ifeq", "ifne", "iflt", "ifge", "ifgt", "ifle",
"if_icmpeq", "if_icmpne", "if_icmplt", "if_icmpge", "if_icmpgt",
"if_icmple", "if_acmpeq", "if_acmpne", "goto", "jsr", "ret",
"tableswitch", "lookupswitch", "ireturn", "lreturn", "freturn",
"dreturn", "areturn", "return", "getstatic", "putstatic",
"getfield", "putfield", "invokevirtual", "invokespecial",
"invokestatic", "invokeinterface", ILLEGAL_OPCODE, "new",
"newarray", "anewarray", "arraylength", "athrow", "checkcast",
"instanceof", "monitorenter", "monitorexit", "wide",
"multianewarray", "ifnull", "ifnonnull", "goto_w", "jsr_w",
"breakpoint", ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
ILLEGAL_OPCODE, ILLEGAL_OPCODE };
// TODO: make those missing (the rup/ms specific ones, but are they
// reachable?)
/**
* Get the name using the opcode. Used when WCA toWCAString().
*
* @param opcode
* @return name or "ILLEGAL_OPCODE"
*/
public static String getNameFromOpcode(int opcode) {
return OPCODE_NAMES[opcode];
}
/**
* See the WCET values
* @return table body of opcodes with info
*/
public String toWCAString() {
StringBuffer sb = new StringBuffer();
sb.append("Table of WCETInstruction cycles\n");
sb
.append("=============================================================\n");
sb
.append("Instruction Hit cycles Miss cycles Mich. info\n");
sb.append(" n=0/1000 n=0/1000\n");
sb
.append("-------------------------------------------------------------\n");
for (int op = 0; op <= 255; op++) {
// name (25)
String str = new String("[" + op + "] " + getNameFromOpcode(op));
sb.append(MiscUtils.postpad(str, 25));
//hit n={0,1000}
String hitstr = getCycles(op, false, 0) + "/"
+ getCycles(op, false, 1000);
hitstr = MiscUtils.prepad(hitstr, 12);
//miss n={0,1000}
String missstr = getCycles(op, true, 0) + "/"
+ getCycles(op, true, 1000);
missstr = MiscUtils.prepad(missstr, 12);
sb.append(hitstr + missstr + "\n");
}
sb
.append("=============================================================\n");
sb.append("Info: b(n=1000)=" + calculateB(false, 1000) + " c=" + c() + " r=" + r
+ " w=" + w + "\n");
sb
.append("Signatures: V void, Z boolean, B byte, C char, S short, I int, J long, F float, D double, L class, [ array\n");
return sb.toString();
}
public static void main(String[] args) {
WCETInstruction inst = new WCETInstruction(DEFAULT_R, DEFAULT_W);
for (int i=0; i<256; ++i) {
int cnt = inst.getCycles(i, false, 0);
if (cnt==-1) cnt = 1000;
System.out.println(i+"\t"+cnt);
}
}
/**
* Returns the wcet count for the instruction.
*
* @see table D.1 in ms thesis
* @param opcode
* @param pmiss <code>true</code> if the instruction referenced by
* <code>opcode</code> causes a cache miss, and <code>false</code> otherwise
* @param n for invoke/return instructions, the length of the receiver/caller in words,
* 0 otherwise
* @return wcet cycle count or -1 if wcet not available
*/
public int getCycles(int opcode, boolean pmiss, int n) {
int wcet = -1;
// cache load time
int loadTime = calculateB(!pmiss, n);
switch (opcode) {
// NOP = 0
case org.apache.bcel.Constants.NOP:
wcet = 1;
break;
// ACONST_NULL = 1
case org.apache.bcel.Constants.ACONST_NULL:
wcet = 1;
break;
// ICONST_M1 = 2
case org.apache.bcel.Constants.ICONST_M1:
wcet = 1;
break;
// ICONST_0 = 3
case org.apache.bcel.Constants.ICONST_0:
wcet = 1;
break;
// ICONST_1 = 4
case org.apache.bcel.Constants.ICONST_1:
wcet = 1;
break;
// ICONST_2 = 5
case org.apache.bcel.Constants.ICONST_2:
wcet = 1;
break;
// ICONST_3 = 6
case org.apache.bcel.Constants.ICONST_3:
wcet = 1;
break;
// ICONST_4 = 7
case org.apache.bcel.Constants.ICONST_4:
wcet = 1;
break;
// ICONST_5 = 8
case org.apache.bcel.Constants.ICONST_5:
wcet = 1;
break;
// LCONST_0 = 9
case org.apache.bcel.Constants.LCONST_0:
wcet = 2;
break;
// LCONST_1 = 10
case org.apache.bcel.Constants.LCONST_1:
wcet = 2;
break;
// FCONST_0 = 11
case org.apache.bcel.Constants.FCONST_0:
wcet = 1;
break;
// FCONST_1 = 12
case org.apache.bcel.Constants.FCONST_1:
wcet = -1;
break;
// FCONST_2 = 13
case org.apache.bcel.Constants.FCONST_2:
wcet = -1;
break;
// DCONST_0 = 14
case org.apache.bcel.Constants.DCONST_0:
wcet = 2;
break;
// DCONST_1 = 15
case org.apache.bcel.Constants.DCONST_1:
wcet = -1;
break;
// BIPUSH = 16
case org.apache.bcel.Constants.BIPUSH:
wcet = 2;
break;
// SIPUSH = 17
case org.apache.bcel.Constants.SIPUSH:
wcet = 3;
break;
// LDC = 18
case org.apache.bcel.Constants.LDC:
wcet = 7 + r;
if (cmp==true)
wcet = ldc.wcet;
break;
// LDC_W = 19
case org.apache.bcel.Constants.LDC_W:
wcet = 8 + r;
if (cmp==true)
wcet = ldc_w.wcet;
break;
// LDC2_W = 20
case org.apache.bcel.Constants.LDC2_W:
wcet = 17;
if (r > 2) {
wcet += r - 2;
}
if (r > 1) {
wcet += r - 1;
}
if (cmp==true){
wcet = ldc2_w.wcet;
}
break;
// ILOAD = 21
case org.apache.bcel.Constants.ILOAD:
wcet = 2;
break;
// LLOAD = 22
case org.apache.bcel.Constants.LLOAD:
wcet = 11;
break;
// FLOAD = 23
case org.apache.bcel.Constants.FLOAD:
wcet = 2;
break;
// DLOAD = 24
case org.apache.bcel.Constants.DLOAD:
wcet = 11;
break;
// ALOAD = 25
case org.apache.bcel.Constants.ALOAD:
wcet = 2;
break;
// ILOAD_0 = 26
case org.apache.bcel.Constants.ILOAD_0:
wcet = 1;
break;
// ILOAD_1 = 27
case org.apache.bcel.Constants.ILOAD_1:
wcet = 1;
break;
// ILOAD_2 = 28
case org.apache.bcel.Constants.ILOAD_2:
wcet = 1;
break;
// ILOAD_3 = 29
case org.apache.bcel.Constants.ILOAD_3:
wcet = 1;
break;
// LLOAD_0 = 30
case org.apache.bcel.Constants.LLOAD_0:
wcet = 2;
break;
// LLOAD_1 = 31
case org.apache.bcel.Constants.LLOAD_1:
wcet = 2;
break;
// LLOAD_2 = 32
case org.apache.bcel.Constants.LLOAD_2:
wcet = 2;
break;
// LLOAD_3 = 33
case org.apache.bcel.Constants.LLOAD_3:
wcet = 11;
break;
// FLOAD_0 = 34
case org.apache.bcel.Constants.FLOAD_0:
wcet = 1;
break;
// FLOAD_1 = 35
case org.apache.bcel.Constants.FLOAD_1:
wcet = 1;
break;
// FLOAD_2 = 36
case org.apache.bcel.Constants.FLOAD_2:
wcet = 1;
break;
// FLOAD_3 = 37
case org.apache.bcel.Constants.FLOAD_3:
wcet = 1;
break;
// DLOAD_0 = 38
case org.apache.bcel.Constants.DLOAD_0:
wcet = 2;
break;
// DLOAD_1 = 39
case org.apache.bcel.Constants.DLOAD_1:
wcet = 2;
break;
// DLOAD_2 = 40
case org.apache.bcel.Constants.DLOAD_2:
wcet = 2;
break;
// DLOAD_3 = 41
case org.apache.bcel.Constants.DLOAD_3:
wcet = 11;
break;
// ALOAD_0 = 42
case org.apache.bcel.Constants.ALOAD_0:
wcet = 1;
break;
// ALOAD_1 = 43
case org.apache.bcel.Constants.ALOAD_1:
wcet = 1;
break;
// ALOAD_2 = 44
case org.apache.bcel.Constants.ALOAD_2:
wcet = 1;
break;
// ALOAD_3 = 45
case org.apache.bcel.Constants.ALOAD_3:
wcet = 1;
break;
// IALOAD = 46
case org.apache.bcel.Constants.IALOAD:
wcet = 6 + 3*r;
if (cmp==true)
wcet = xaload.wcet;
break;
// LALOAD = 47
case org.apache.bcel.Constants.LALOAD:
if(cmp==false){
wcet = 43+4*r;}
else{
wcet = -1;} // not yet implemented
break;
// FALOAD = 48
case org.apache.bcel.Constants.FALOAD:
wcet = 6 + 3*r;
if (cmp==true)
wcet = xaload.wcet;
break;
// DALOAD = 49
case org.apache.bcel.Constants.DALOAD:
if(cmp==false){
wcet = 43+4*r;}
else{
wcet = -1;} // not yet implemented
break;
// AALOAD = 50
case org.apache.bcel.Constants.AALOAD:
wcet = 6 + 3*r;
if (cmp==true)
wcet = xaload.wcet;
break;
// BALOAD = 51
case org.apache.bcel.Constants.BALOAD:
wcet = 6 + 3*r;
if (cmp==true)
wcet = xaload.wcet;
break;
// CALOAD = 52
case org.apache.bcel.Constants.CALOAD:
wcet = 6 + 3*r;
if (cmp==true)
wcet = xaload.wcet;
break;
// SALOAD = 53
case org.apache.bcel.Constants.SALOAD:
wcet = 6 + 3*r;
if (cmp==true)
wcet = xaload.wcet;
break;
// ISTORE = 54
case org.apache.bcel.Constants.ISTORE:
wcet = 2;
break;
// LSTORE = 55
case org.apache.bcel.Constants.LSTORE:
wcet = 11;
break;
// FSTORE = 56
case org.apache.bcel.Constants.FSTORE:
wcet = 2;
break;
// DSTORE = 57
case org.apache.bcel.Constants.DSTORE:
wcet = 11;
break;
// ASTORE = 58
case org.apache.bcel.Constants.ASTORE:
wcet = 2;
break;
// ISTORE_0 = 59
case org.apache.bcel.Constants.ISTORE_0:
wcet = 1;
break;
// ISTORE_1 = 60
case org.apache.bcel.Constants.ISTORE_1:
wcet = 1;
break;
// ISTORE_2 = 61
case org.apache.bcel.Constants.ISTORE_2:
wcet = 1;
break;
// ISTORE_3 = 62
case org.apache.bcel.Constants.ISTORE_3:
wcet = 1;
break;
// LSTORE_0 = 63
case org.apache.bcel.Constants.LSTORE_0:
wcet = 2;
break;
// LSTORE_1 = 64
case org.apache.bcel.Constants.LSTORE_1:
wcet = 2;
break;
// LSTORE_2 = 65
case org.apache.bcel.Constants.LSTORE_2:
wcet = 2;
break;
// LSTORE_3 = 66
case org.apache.bcel.Constants.LSTORE_3:
wcet = 11;
break;
// FSTORE_0 = 67
case org.apache.bcel.Constants.FSTORE_0:
wcet = 1;
break;
// FSTORE_1 = 68
case org.apache.bcel.Constants.FSTORE_1:
wcet = 1;
break;
// FSTORE_2 = 69
case org.apache.bcel.Constants.FSTORE_2:
wcet = 1;
break;
// FSTORE_3 = 70
case org.apache.bcel.Constants.FSTORE_3:
wcet = 1;
break;
// DSTORE_0 = 71
case org.apache.bcel.Constants.DSTORE_0:
wcet = 2;
break;
// DSTORE_1 = 72
case org.apache.bcel.Constants.DSTORE_1:
wcet = 2;
break;
// DSTORE_2 = 73
case org.apache.bcel.Constants.DSTORE_2:
wcet = 2;
break;
// DSTORE_3 = 74
case org.apache.bcel.Constants.DSTORE_3:
wcet = 11;
break;
// ASTORE_0 = 75
case org.apache.bcel.Constants.ASTORE_0:
wcet = 1;
break;
// ASTORE_1 = 76
case org.apache.bcel.Constants.ASTORE_1:
wcet = 1;
break;
// ASTORE_2 = 77
case org.apache.bcel.Constants.ASTORE_2:
wcet = 1;
break;
// ASTORE_3 = 78
case org.apache.bcel.Constants.ASTORE_3:
wcet = 1;
break;
// IASTORE = 79
case org.apache.bcel.Constants.IASTORE:
wcet = 10+2*r+w;
if (cmp==true)
wcet = xastore.wcet;
break;
// LASTORE = 80
case org.apache.bcel.Constants.LASTORE:
if(cmp==false){
wcet = 48+2*r+w;
if (w > 3) {
wcet += w - 3;}
}
else{
wcet = -1;} // not yet implemented
break;
// FASTORE = 81
case org.apache.bcel.Constants.FASTORE:
wcet = 10+2*r+w;
if (cmp==true)
wcet = xastore.wcet;
break;
// DASTORE = 82
case org.apache.bcel.Constants.DASTORE:
if(cmp==false){
wcet = 48+2*r+w;
if (w > 3) {
wcet += w - 3;}
}
else{
wcet = -1;} // not yet implemented
break;
// AASTORE = 83
case org.apache.bcel.Constants.AASTORE:
// wcet = 10+2*r+w;
// now with write barrier
wcet = -1;
break;
// BASTORE = 84
case org.apache.bcel.Constants.BASTORE:
wcet = 10+2*r+w;
if (cmp==true)
wcet = xastore.wcet;
break;
// CASTORE = 85
case org.apache.bcel.Constants.CASTORE:
wcet = 10+2*r+w;
if (cmp==true)
wcet = xastore.wcet;
break;
// SASTORE = 86
case org.apache.bcel.Constants.SASTORE:
wcet = 10+2*r+w;
if (cmp==true)
wcet = xastore.wcet;
break;
// POP = 87
case org.apache.bcel.Constants.POP:
wcet = 1;
break;
// POP2 = 88
case org.apache.bcel.Constants.POP2:
wcet = 2;
break;
// DUP = 89
case org.apache.bcel.Constants.DUP:
wcet = 1;
break;
// DUP_X1 = 90
case org.apache.bcel.Constants.DUP_X1:
wcet = 5;
break;
// DUP_X2 = 91
case org.apache.bcel.Constants.DUP_X2:
wcet = 7;
break;
// DUP2 = 92
case org.apache.bcel.Constants.DUP2:
wcet = 6;
break;
// DUP2_X1 = 93
case org.apache.bcel.Constants.DUP2_X1:
wcet = 8;
break;
// DUP2_X2 = 94
case org.apache.bcel.Constants.DUP2_X2:
wcet = 10;
break;
// SWAP = 95
case org.apache.bcel.Constants.SWAP:
wcet = 4;
break;
// IADD = 96
case org.apache.bcel.Constants.IADD:
wcet = 1;
break;
// LADD = 97
case org.apache.bcel.Constants.LADD:
wcet = 26;
break;
// FADD = 98
case org.apache.bcel.Constants.FADD:
wcet = -1;
break;
// DADD = 99
case org.apache.bcel.Constants.DADD:
wcet = -1;
break;
// ISUB = 100
case org.apache.bcel.Constants.ISUB:
wcet = 1;
break;
// LSUB = 101
case org.apache.bcel.Constants.LSUB:
wcet = 38;
break;
// FSUB = 102
case org.apache.bcel.Constants.FSUB:
wcet = -1;
break;
// DSUB = 103
case org.apache.bcel.Constants.DSUB:
wcet = -1;
break;
// IMUL = 104
case org.apache.bcel.Constants.IMUL:
wcet = 19;
break;
// LMUL = 105
case org.apache.bcel.Constants.LMUL:
wcet = -1;
break;
// FMUL = 106
case org.apache.bcel.Constants.FMUL:
wcet = -1;
break;
// DMUL = 107
case org.apache.bcel.Constants.DMUL:
wcet = -1;
break;
// IDIV = 108
case org.apache.bcel.Constants.IDIV:
wcet = -1;
break;
// LDIV = 109
case org.apache.bcel.Constants.LDIV:
wcet = -1;
break;
// FDIV = 110
case org.apache.bcel.Constants.FDIV:
wcet = -1;
break;
// DDIV = 111
case org.apache.bcel.Constants.DDIV:
wcet = -1;
break;
// IREM = 112
case org.apache.bcel.Constants.IREM:
wcet = -1;
break;
// LREM = 113
case org.apache.bcel.Constants.LREM:
wcet = -1;
break;
// FREM = 114
case org.apache.bcel.Constants.FREM:
wcet = -1;
break;
// DREM = 115
case org.apache.bcel.Constants.DREM:
wcet = -1;
break;
// INEG = 116
case org.apache.bcel.Constants.INEG:
wcet = 4;
break;
// LNEG = 117
case org.apache.bcel.Constants.LNEG:
wcet = 34;
break;
// FNEG = 118
case org.apache.bcel.Constants.FNEG:
wcet = -1;
break;
// DNEG = 119
case org.apache.bcel.Constants.DNEG:
wcet = -1;
break;
// ISHL = 120
case org.apache.bcel.Constants.ISHL:
wcet = 1;
break;
// LSHL = 121
case org.apache.bcel.Constants.LSHL:
wcet = 28;
break;
// ISHR = 122
case org.apache.bcel.Constants.ISHR:
wcet = 1;
break;
// LSHR = 123
case org.apache.bcel.Constants.LSHR:
wcet = 28;
break;
// IUSHR = 124
case org.apache.bcel.Constants.IUSHR:
wcet = 1;
break;
// LUSHR = 125
case org.apache.bcel.Constants.LUSHR:
wcet = 28;
break;
// IAND = 126
case org.apache.bcel.Constants.IAND:
wcet = 1;
break;
// LAND = 127
case org.apache.bcel.Constants.LAND:
wcet = 8;
break;
// IOR = 128
case org.apache.bcel.Constants.IOR:
wcet = 1;
break;
// LOR = 129
case org.apache.bcel.Constants.LOR:
wcet = 8;
break;
// IXOR = 130
case org.apache.bcel.Constants.IXOR:
wcet = 1;
break;
// LXOR = 131
case org.apache.bcel.Constants.LXOR:
wcet = 8;
break;
// IINC = 132
case org.apache.bcel.Constants.IINC:
wcet = 8;
break;
// I2L = 133
case org.apache.bcel.Constants.I2L:
wcet = 5;
break;
// I2F = 134
case org.apache.bcel.Constants.I2F:
wcet = -1;
break;
// I2D = 135
case org.apache.bcel.Constants.I2D:
wcet = -1;
break;
// L2I = 136
case org.apache.bcel.Constants.L2I:
wcet = 3;
break;
// L2F = 137
case org.apache.bcel.Constants.L2F:
wcet = -1;
break;
// L2D = 138
case org.apache.bcel.Constants.L2D:
wcet = -1;
break;
// F2I = 139
case org.apache.bcel.Constants.F2I:
wcet = -1;
break;
// F2L = 140
case org.apache.bcel.Constants.F2L:
wcet = -1;
break;
// F2D = 141
case org.apache.bcel.Constants.F2D:
wcet = -1;
break;
// D2I = 142
case org.apache.bcel.Constants.D2I:
wcet = -1;
break;
// D2L = 143
case org.apache.bcel.Constants.D2L:
wcet = -1;
break;
// D2F = 144
case org.apache.bcel.Constants.D2F:
wcet = -1;
break;
// I2B = 145
case org.apache.bcel.Constants.I2B:
wcet = -1;
break;
// INT2BYTE = 145 // Old notion
// case org.apache.bcel.Constants.INT2BYTE : wcet = -1; break;
// I2C = 146
case org.apache.bcel.Constants.I2C:
wcet = 2;
break;
// INT2CHAR = 146 // Old notion
// case org.apache.bcel.Constants.INT2CHAR : wcet = -1; break;
// I2S = 147
case org.apache.bcel.Constants.I2S:
wcet = -1;
break;
// INT2SHORT = 147 // Old notion
// case org.apache.bcel.Constants.INT2SHORT : wcet = -1; break;
// LCMP = 148
case org.apache.bcel.Constants.LCMP:
wcet = 85;
break;
// FCMPL = 149
case org.apache.bcel.Constants.FCMPL:
wcet = -1;
break;
// FCMPG = 150
case org.apache.bcel.Constants.FCMPG:
wcet = -1;
break;
// DCMPL = 151
case org.apache.bcel.Constants.DCMPL:
wcet = -1;
break;
// DCMPG = 152
case org.apache.bcel.Constants.DCMPG:
wcet = -1;
break;
// IFEQ = 153
case org.apache.bcel.Constants.IFEQ:
wcet = 4;
break;
// IFNE = 154
case org.apache.bcel.Constants.IFNE:
wcet = 4;
break;
// IFLT = 155
case org.apache.bcel.Constants.IFLT:
wcet = 4;
break;
// IFGE = 156
case org.apache.bcel.Constants.IFGE:
wcet = 4;
break;
// IFGT = 157
case org.apache.bcel.Constants.IFGT:
wcet = 4;
break;
// IFLE = 158
case org.apache.bcel.Constants.IFLE:
wcet = 4;
break;
// IF_ICMPEQ = 159
case org.apache.bcel.Constants.IF_ICMPEQ:
wcet = 4;
break;
// IF_ICMPNE = 160
case org.apache.bcel.Constants.IF_ICMPNE:
wcet = 4;
break;
// IF_ICMPLT = 161
case org.apache.bcel.Constants.IF_ICMPLT:
wcet = 4;
break;
// IF_ICMPGE = 162
case org.apache.bcel.Constants.IF_ICMPGE:
wcet = 4;
break;
// IF_ICMPGT = 163
case org.apache.bcel.Constants.IF_ICMPGT:
wcet = 4;
break;
// IF_ICMPLE = 164
case org.apache.bcel.Constants.IF_ICMPLE:
wcet = 4;
break;
// IF_ACMPEQ = 165
case org.apache.bcel.Constants.IF_ACMPEQ:
wcet = 4;
break;
// IF_ACMPNE = 166
case org.apache.bcel.Constants.IF_ACMPNE:
wcet = 4;
break;
// GOTO = 167
case org.apache.bcel.Constants.GOTO:
wcet = 4;
break;
// JSR = 168
case org.apache.bcel.Constants.JSR:
wcet = -1;
break;
// RET = 169
case org.apache.bcel.Constants.RET:
wcet = -1; // TODO: Should this be 1?
break;
// TABLESWITCH = 170
case org.apache.bcel.Constants.TABLESWITCH:
wcet = -1;
break;
// LOOKUPSWITCH = 171
case org.apache.bcel.Constants.LOOKUPSWITCH:
wcet = -1;
break;
// IRETURN = 172
case org.apache.bcel.Constants.IRETURN:
wcet = 23;
if (r > 3) {
wcet += r - 3;
}
if (loadTime > IRETURN_HIDDEN_LOAD_CYCLES) {
wcet += loadTime - IRETURN_HIDDEN_LOAD_CYCLES;
}
if(cmp==true){
WCETMemInstruction ireturn = new WCETMemInstruction();
ireturn.microcode = new int [wcet];
ireturn.opcode = 172;
generateInstruction(ireturn, pmiss, n, loadTime);
wcet = wcetOfInstruction(ireturn.microcode);
}
break;
// LRETURN = 173
case org.apache.bcel.Constants.LRETURN:
wcet = 25;
if (r > 3) {
wcet += r - 3;
}
if (loadTime > LRETURN_HIDDEN_LOAD_CYCLES) {
wcet += loadTime - LRETURN_HIDDEN_LOAD_CYCLES;
}
if(cmp==true){
wcet = -1;}
break;
// FRETURN = 174
case org.apache.bcel.Constants.FRETURN:
wcet = 23;
if (r > 3) {
wcet += r - 3;
}
if (loadTime > FRETURN_HIDDEN_LOAD_CYCLES) {
wcet += loadTime - FRETURN_HIDDEN_LOAD_CYCLES;
}
if(cmp==true){
WCETMemInstruction freturn = new WCETMemInstruction();
freturn.microcode = new int [wcet];
freturn.opcode = 174;
generateInstruction(freturn, pmiss, n, loadTime);
wcet = wcetOfInstruction(freturn.microcode);}
break;
// DRETURN = 175
case org.apache.bcel.Constants.DRETURN:
wcet = 25;
if (r > 3) {
wcet += r - 3;
}
if (loadTime > DRETURN_HIDDEN_LOAD_CYCLES) {
wcet += loadTime - DRETURN_HIDDEN_LOAD_CYCLES;
}
if(cmp==true){
wcet = -1;}
break;
// ARETURN = 176
case org.apache.bcel.Constants.ARETURN:
wcet = 23;
if (r > 3) {
wcet += r - 3;
}
if (loadTime > ARETURN_HIDDEN_LOAD_CYCLES) {
wcet += loadTime - ARETURN_HIDDEN_LOAD_CYCLES;
}
if(cmp==true){
WCETMemInstruction areturn = new WCETMemInstruction();
areturn.microcode = new int [wcet];
areturn.opcode = 176;
generateInstruction(areturn, pmiss, n, loadTime);
wcet = wcetOfInstruction(areturn.microcode);}
break;
// RETURN = 177
case org.apache.bcel.Constants.RETURN:
wcet = 21;
if (r > 3) {
wcet += r - 3;
}
if (loadTime > RETURN_HIDDEN_LOAD_CYCLES) {
wcet += loadTime - RETURN_HIDDEN_LOAD_CYCLES;
}
if(cmp==true){
WCETMemInstruction returnx = new WCETMemInstruction();
returnx.microcode = new int [wcet];
returnx.opcode = 177;
generateInstruction(returnx, pmiss, n, loadTime);
wcet = wcetOfInstruction(returnx.microcode);
}
break;
// GETSTATIC = 178
case org.apache.bcel.Constants.GETSTATIC:
wcet = 5 + r;
if (cmp==true)
wcet = getstaticx.wcet;
break;
// PUTSTATIC = 179
case org.apache.bcel.Constants.PUTSTATIC:
wcet = 5 + w;
if (cmp==true)
wcet = putstatic.wcet;
break;
// GETFIELD = 180
case org.apache.bcel.Constants.GETFIELD:
wcet = 8 + 2 * r;
if (cmp==true)
wcet = getfield.wcet;
break;
// PUTFIELD = 181
case org.apache.bcel.Constants.PUTFIELD:
wcet = 9 + r + w;
if (cmp==true)
wcet = putfield.wcet;
break;
// INVOKEVIRTUAL = 182
case org.apache.bcel.Constants.INVOKEVIRTUAL:
wcet = 98 + 2 * r;
if (r > 3) {
wcet += r - 3;
}
if (r > 2) {
wcet += r - 2;
}
if (loadTime > INVOKE_HIDDEN_LOAD_CYCLES) {
wcet += loadTime - INVOKE_HIDDEN_LOAD_CYCLES;
}
if(cmp==true){
WCETMemInstruction invokevirtual = new WCETMemInstruction();
invokevirtual.microcode = new int [wcet];
invokevirtual.opcode = 182;
generateInstruction(invokevirtual, pmiss, n, loadTime);
//for(int i=0; i<invokevirtual.microcode.length; i++)
// System.out.println("Invokevirtual["+i+"] = "+invokevirtual.microcode[i]);
wcet = wcetOfInstruction(invokevirtual.microcode);}
break;
// INVOKESPECIAL = 183
case org.apache.bcel.Constants.INVOKESPECIAL:
wcet = 73 + r;
if (r > 3) {
wcet += r - 3;
}
if (r > 2) {
wcet += r - 2;
}
if (loadTime > INVOKE_HIDDEN_LOAD_CYCLES) {
wcet += loadTime - INVOKE_HIDDEN_LOAD_CYCLES;
}
if(cmp==true){
WCETMemInstruction invokespecial = new WCETMemInstruction();
invokespecial.microcode = new int [wcet];
invokespecial.opcode = 183;
generateInstruction(invokespecial, pmiss, n, loadTime);
wcet = wcetOfInstruction(invokespecial.microcode);}
break;
// INVOKENONVIRTUAL = 183
// case org.apache.bcel.Constants.INVOKENONVIRTUAL : wcet = -1; break;
// INVOKESTATIC = 184
case org.apache.bcel.Constants.INVOKESTATIC:
wcet = 73 + r;
if (r > 3) {
wcet += r - 3;
}
if (r > 2) {
wcet += r - 2;
}
if (loadTime > INVOKE_HIDDEN_LOAD_CYCLES) {
wcet += loadTime - INVOKE_HIDDEN_LOAD_CYCLES;
}
if(cmp==true){
WCETMemInstruction invokestatic = new WCETMemInstruction();
invokestatic.microcode = new int [wcet];
invokestatic.opcode = 184;
generateInstruction(invokestatic, pmiss, n, loadTime);
wcet = wcetOfInstruction(invokestatic.microcode);}
break;
// INVOKEINTERFACE = 185
case org.apache.bcel.Constants.INVOKEINTERFACE:
wcet = 111 + 4 * r;
if (r > 3) {
wcet += r - 3;
}
if (r > 2) {
wcet += r - 2;
}
if (loadTime > INVOKE_HIDDEN_LOAD_CYCLES) {
wcet += loadTime - INVOKE_HIDDEN_LOAD_CYCLES;
}
if(cmp==true){
wcet = -1;}
break;
// NEW = 187
case org.apache.bcel.Constants.NEW:
wcet = -1;
break;
// NEWARRAY = 188
case org.apache.bcel.Constants.NEWARRAY:
wcet = -1;
break;
// ANEWARRAY = 189
case org.apache.bcel.Constants.ANEWARRAY:
wcet = -1;
break;
// ARRAYLENGTH = 190
case org.apache.bcel.Constants.ARRAYLENGTH:
wcet = 6 + r;
if (cmp==true)
wcet = arraylength.wcet;
break;
// ATHROW = 191
case org.apache.bcel.Constants.ATHROW:
wcet = -1;
break;
// CHECKCAST = 192
case org.apache.bcel.Constants.CHECKCAST:
wcet = -1;
break;
// INSTANCEOF = 193
case org.apache.bcel.Constants.INSTANCEOF:
wcet = -1;
break;
// MONITORENTER = 194
case org.apache.bcel.Constants.MONITORENTER:
wcet = 19;
break;
// MONITOREXIT = 195
case org.apache.bcel.Constants.MONITOREXIT:
wcet = 20;
break;
// WIDE = 196
case org.apache.bcel.Constants.WIDE:
wcet = -1;
break;
// MULTIANEWARRAY = 197
case org.apache.bcel.Constants.MULTIANEWARRAY:
wcet = -1;
break;
// IFNULL = 198
case org.apache.bcel.Constants.IFNULL:
wcet = 4;
break;
// IFNONNULL = 199
case org.apache.bcel.Constants.IFNONNULL:
wcet = 4;
break;
// GOTO_W = 200
case org.apache.bcel.Constants.GOTO_W:
wcet = -1;
break;
// JSR_W = 201
case org.apache.bcel.Constants.JSR_W:
wcet = -1;
break;
// JOPSYS_RD = 209
case JOPSYS_RD:
wcet = 4 + r;
if (cmp==true)
wcet = jopsys_rdx.wcet;
break;
// JOPSYS_WR = 210
case JOPSYS_WR:
wcet = 5 + w;
if (cmp==true)
wcet = jopsys_wrx.wcet;
break;
// JOPSYS_RDMEM = 211
case JOPSYS_RDMEM:
wcet = 4 + r;
if (cmp==true)
wcet = jopsys_rdx.wcet;
break;
// JOPSYS_WRMEM = 212
case JOPSYS_WRMEM:
wcet = 5 + w;
if (cmp==true)
wcet = jopsys_wrx.wcet;
break;
// JOPSYS_RDINT = 213
case JOPSYS_RDINT:
wcet = 3;
break;
// JOPSYS_WRINT = 214
case JOPSYS_WRINT:
wcet = 3;
break;
// JOPSYS_GETSP = 215
case JOPSYS_GETSP:
wcet = 3;
break;
// JOPSYS_SETSP = 216
case JOPSYS_SETSP:
wcet = 4;
break;
// JOPSYS_GETVP = 217
case JOPSYS_GETVP:
wcet = 1;
break;
// JOPSYS_SETVP = 218
case JOPSYS_SETVP:
wcet = 2;
break;
// JOPSYS_INT2EXT = 219
case JOPSYS_INT2EXT:
if(cmp==false){
int wt = 0;
if (w>8) wt = w-8;
wcet = 14+r+ n*(23+wt);}
else{
wcet = -1;} // not yet implemented
break;
// JOPSYS_EXT2INT = 220
case JOPSYS_EXT2INT:
if(cmp==false){
int rt = 0;
if (r>10) rt = r-10;
wcet = 14+r+ n*(23+rt);}
else{
wcet = -1;} // not yet implemented
break;
// JOPSYS_NOP = 221
case JOPSYS_NOP:
wcet = 1;
break;
case 223: // conditional move
wcet = 5;
break;
// GETSTATIC_REF = 224
case GETSTATIC_REF:
wcet = 5 + r;
if (cmp==true)
wcet = getstaticx.wcet;
break;
// GETFIELD_REF = 226
case GETFIELD_REF:
wcet = 8 + 2 * r;
if (cmp==true){
WCETMemInstruction getfield_ref = new WCETMemInstruction();
getfield_ref.microcode = new int [wcet];
getfield_ref.opcode = 226;
generateInstruction(getfield_ref, pmiss, n, loadTime);
wcet = wcetOfInstruction(getfield_ref.microcode);
}
break;
// GETSTATIC_LONG = 228
case GETSTATIC_LONG:
wcet = 16 + r;
if (r > 3) {
wcet += r - 3;
}
if (cmp==true)
wcet = -1;
break;
// PUTSTATIC_LONG = 229
case PUTSTATIC_LONG:
wcet = 17 + w;
if (w > 2) {
wcet += w - 2; // bh, 28.9.11: s/w-1/w-2/ according to micropath analysis
}
if (cmp==true)
wcet = -1;
break;
// GETFIELD_LONG = 230
case GETFIELD_LONG:
wcet = 26 + 2*r;
if (r > 3) {
wcet += r - 3;
}
if (cmp==true)
wcet = -1;
break;
// PUTFIELD_LONG = 231
case PUTFIELD_LONG:
wcet = 30 + r + w;
if (w > 1) {
wcet += w - 1;
}
if (cmp==true)
wcet = -1;
break;
// JOPSYS_GETFIELD = 233
case JOPSYS_GETFIELD:
// FIXME: perhaps it is 9 + 2r?
// But MS should check in the HW!
wcet = 9 + 2*r;
if (cmp==true)
wcet = -1;
break;
// JOPSYS_PUTFIELD = 234
case JOPSYS_PUTFIELD:
wcet = 12 + r + w;
if (cmp==true)
wcet = -1;
break;
// JOPSYS_GETSTATIC = 238
case JOPSYS_GETSTATIC:
wcet = 6 + r;
if (cmp==true)
wcet = -1;
break;
// JOPSYS_PUTSTATIC = 239
case JOPSYS_PUTSTATIC:
wcet = 6 + w;
if (cmp==true)
wcet = -1;
break;
// JOPSYS_MEMCPY = 232
case JOPSYS_MEMCPY:
wcet = -1;
break;
// JOPSYS_INVAL = 204
case JOPSYS_INVAL:
wcet = 4;
break;
default:
wcet = -1;
}
// TODO: Add the JOP specific codes?
if (JopInstr.isInJava(opcode)) {
return -1;
}
return wcet;
}
/**
* Check to see if there is a valid WCET count for the instruction.
*
* @param opcode
* @return true if there is a valid wcet value
*/
public boolean wcetAvailable(int opcode) {
if (getCycles(opcode, false, 0) == WCETNOTAVAILABLE)
return false;
else
return true;
}
/**
* Get an estimation of the bytecode execution time.
*
* TODO: measure Java implemented bytecodes and add the numbers.
* @param opcode
* @param pmiss
* @param n
* @return
*/
public int getCyclesEstimate(int opcode, boolean pmiss, int n) {
int ret = getCycles(opcode, pmiss, n);
// VERY rough estimate
if (ret==WCETNOTAVAILABLE) {
ret = 200;
}
return ret;
}
public int getNoImplDispatchCycles() {
// FIXME (CMP_WCET): invokevirtual should be a conservative approximation to sys_noim for now
if(cmp) return getCycles(org.apache.bcel.Constants.INVOKEVIRTUAL,false,0);
else return 85 + Math.max(0,r-3) + Math.max(0,r-2);
}
/**
* Method load time on invoke or return if there is a cache miss (see pMiss).
*
* @see ms thesis p 232
*/
public int calculateB(boolean hit, int n) {
int b = -1;
if (n == -1) {
System.err.println("n not set!");
System.exit(-1);
} else {
if (hit) {
b = 4;
} else {
b = 6 + (n+1) * (2+c());
}
}
return b;
}
// Initializes a couple of periods, where one timeslot is true and the
// other ones are false
public void initArbiter(){
int i;
int arb_period = getArbiterPeriod();
arbiter = new boolean [MAX_CYCLES];
for(i=0;i<MAX_CYCLES;i++){
if( (i % arb_period) < timeslot ){
arbiter[i]=true;}
else{
arbiter[i]=false;}
}
}
// generates all static instruction patterns and WCETs
public void generateStaticInstr()
{
ldc = new WCETMemInstruction();
ldc_w = new WCETMemInstruction();
ldc2_w = new WCETMemInstruction();
xaload = new WCETMemInstruction();
xastore = new WCETMemInstruction();
getstaticx = new WCETMemInstruction();
putstatic = new WCETMemInstruction();
getfield = new WCETMemInstruction();
putfield = new WCETMemInstruction();
arraylength = new WCETMemInstruction();
jopsys_rdx = new WCETMemInstruction();
jopsys_wrx = new WCETMemInstruction();
ldc.microcode = new int [7+r];
ldc.opcode = 18;
generateInstruction(ldc, false, 0, 0); // Cache is not interesting here
ldc.wcet = wcetOfInstruction(ldc.microcode);
ldc_w.microcode = new int [8+r];
ldc_w.opcode = 19;
generateInstruction(ldc_w, false, 0, 0);
ldc_w.wcet = wcetOfInstruction(ldc_w.microcode);
int wcet = 17;
if (r > 2) {
wcet += r - 2;
}
if (r > 1) {
wcet += r - 1;
}
ldc2_w.microcode = new int [wcet];
ldc2_w.opcode = 20;
generateInstruction(ldc2_w, false, 0, 0);
ldc2_w.wcet = wcetOfInstruction(ldc2_w.microcode);
xaload.microcode = new int [7+3*r];
xaload.opcode = 46;
generateInstruction(xaload, false, 0, 0);
xaload.wcet = wcetOfInstruction(xaload.microcode);
xastore.microcode = new int [10+2*r+w];
xastore.opcode = 79;
generateInstruction(xastore, false, 0, 0);
xastore.wcet = wcetOfInstruction(xastore.microcode);
getstaticx.microcode = new int [5+r];
getstaticx.opcode = 178;
generateInstruction(getstaticx, false, 0, 0);
getstaticx.wcet = wcetOfInstruction(getstaticx.microcode);
putstatic.microcode = new int [5+w];
putstatic.opcode = 179;
generateInstruction(putstatic, false, 0, 0);
putstatic.wcet = wcetOfInstruction(putstatic.microcode);
getfield.microcode = new int [8+2*r];
getfield.opcode = 180;
generateInstruction(getfield, false, 0, 0);
getfield.wcet = wcetOfInstruction(getfield.microcode);
putfield.microcode = new int [9+r+w];
putfield.opcode = 181;
generateInstruction(putfield, false, 0, 0);
putfield.wcet = wcetOfInstruction(putfield.microcode);
arraylength.microcode = new int [6+r];
arraylength.opcode = 190;
generateInstruction(arraylength, false, 0, 0);
arraylength.wcet = wcetOfInstruction(arraylength.microcode);
jopsys_rdx.microcode = new int [4+r];
jopsys_rdx.opcode = 209;
generateInstruction(jopsys_rdx, false, 0, 0);
jopsys_rdx.wcet = wcetOfInstruction(jopsys_rdx.microcode);
jopsys_wrx.microcode = new int [5+w];
jopsys_wrx.opcode = 210;
generateInstruction(jopsys_wrx, false, 0, 0);
jopsys_wrx.wcet = wcetOfInstruction(jopsys_wrx.microcode);
}
// Generates the Instruction patterns
public void generateInstruction(WCETMemInstruction instruction, boolean pmiss, int n, int b){
int cnt = 0;
int x = 0;
int y = 0;
switch(instruction.opcode){
// Static Instructions
// ldc
case 18:
for(int i=0;i<instruction.microcode.length;i++){
if(i<=4) instruction.microcode[i]=NOP;
else if(i==5) instruction.microcode[i]=RD;
else instruction.microcode[i]=NOP;
}
break;
// ldc_w
case 19:
for(int i=0;i<instruction.microcode.length;i++){
if(i<=5) instruction.microcode[i]=NOP;
else if(i==6) instruction.microcode[i]=RD;
else instruction.microcode[i]=NOP;
}
break;
// ldc2_w
case 20:
if (r <= 2) x = 0;
else x = r-2; // the 2nd comparison is unnecessary because only only NOPs anyway!
for(int i=0;i<instruction.microcode.length;i++){
if(i<=6) instruction.microcode[i]=NOP;
else if(i==7) instruction.microcode[i]=RD;
else if(i>=8 && i<=13+x) instruction.microcode[i]=NOP;
else if(i==14+x) instruction.microcode[i]=RD;
else instruction.microcode[i]=NOP;
}
break;
// xaload = iaload, faload, aaload, baload, caload, saload
case 46:
case 48:
case 50:
case 51:
case 52:
for(int i=0;i<instruction.microcode.length;i++){
if(i<=2) instruction.microcode[i]=NOP;
else if(i==3) instruction.microcode[i]=RD;
else if(i>3 && i<=3+r) instruction.microcode[i]=NOP;
else if(i==4+r) instruction.microcode[i]=RD;
else if(i>4+r && i<=4+2*r) instruction.microcode[i]=NOP;
else if(i==5+2*r) instruction.microcode[i]=RD;
else instruction.microcode[i]=NOP;
}
break;
// xastore = iastore, fastore, bastore, castore, sastore
case 79:
case 81:
case 84:
case 85:
case 86:
for(int i=0;i<instruction.microcode.length;i++){
if(i<=3) instruction.microcode[i]=NOP;
else if(i==4) instruction.microcode[i]=RD;
else if(i>4 && i<=4+r) instruction.microcode[i]=NOP;
else if(i==5+r) instruction.microcode[i]=RD;
else if(i>5+r && i<=7+2*r) instruction.microcode[i]=NOP;
else if(i==8+2*r) instruction.microcode[i]=WR;
else instruction.microcode[i]=NOP;
}
break;
// getstaticx = getstatic, getstatic_ref
case 178:
case 224:
for(int i=0;i<instruction.microcode.length;i++){
if(i<=2) instruction.microcode[i]=NOP;
else if(i==3) instruction.microcode[i]=RD;
else instruction.microcode[i]=NOP;
}
break;
// putstatic
case 179:
// TODO: is this pattern correct, but it does not really matter
// for single bytecode WCET values
for(int i=0;i<instruction.microcode.length;i++){
if(i<=2) instruction.microcode[i]=NOP;
else if(i==3) instruction.microcode[i]=WR;
else instruction.microcode[i]=NOP;
}
break;
// getfield
case 180:
for(int i=0;i<instruction.microcode.length;i++){
if(i<=2) instruction.microcode[i]=NOP;
else if(i==3) instruction.microcode[i]=RD;
else if(i>3 && i<=5+r) instruction.microcode[i]=NOP;
else if(i==6+r) instruction.microcode[i]=RD;
else instruction.microcode[i]=NOP;
}
break;
// putfield
case 181:
for(int i=0;i<instruction.microcode.length;i++){
if(i<=3) instruction.microcode[i]=NOP;
else if(i==4) instruction.microcode[i]=RD;
else if(i>4 && i<=6+r) instruction.microcode[i]=NOP;
else if(i==7+r) instruction.microcode[i]=WR;
else instruction.microcode[i]=NOP;
}
break;
// arraylength
case 190:
for(int i=0;i<instruction.microcode.length;i++){
if(i<=3) instruction.microcode[i]=NOP;
else if(i==4) instruction.microcode[i]=RD;
else instruction.microcode[i]=NOP;
}
break;
// jopsys_rdx = jopsys_rd, jopsys_rdmem
case 209:
case 211:
for(int i=0;i<instruction.microcode.length;i++){
if(i<=1) instruction.microcode[i]=NOP;
else if(i==2) instruction.microcode[i]=RD;
else instruction.microcode[i]=NOP;
}
break;
// jopsys_wrx = jopsys_wr, jopsys_wrmem
case 210:
case 212:
for(int i=0;i<instruction.microcode.length;i++){
if(i<=2) instruction.microcode[i]=NOP;
else if(i==3) instruction.microcode[i]=WR;
else instruction.microcode[i]=NOP;
}
break;
// Dynamic Instructions
// ireturn, freturn, areturn
case 172:
case 174:
case 176:
if (r <= 3) x = 0;
else x = r-3;
for(int i=0;i<instruction.microcode.length;i++){
if(i<=3) instruction.microcode[i]=NOP;
else if(i==4) instruction.microcode[i]=RD;
else if(i>=5 && i<=15+x) instruction.microcode[i]=NOP;
else{
if (pmiss == false || n==0)
instruction.microcode[i]=NOP;
else{
if (cnt<(2+c())*(n+1)){
if (cnt % (r+1) == 0){
instruction.microcode[i]=RD;
cnt++;}
else{
instruction.microcode[i]=NOP;
cnt++;}
}
else
instruction.microcode[i]=NOP;
}
}
}
break;
// lreturn
case 173:
break;
// dreturn
case 175:
break;
// return
case 177:
if (r <= 3) x = 0;
else x = r-3;
for(int i=0;i<instruction.microcode.length;i++){
if(i<=2) instruction.microcode[i]=NOP;
else if(i==3) instruction.microcode[i]=RD;
else if(i>=4 && i<=14+x) instruction.microcode[i]=NOP;
else{
if (pmiss == false || n==0)
instruction.microcode[i]=NOP;
else{
if (cnt<(2+c())*(n+1)){
if (cnt % (r+1) == 0){
instruction.microcode[i]=RD;
cnt++;}
else{
instruction.microcode[i]=NOP;
cnt++;}
}
else
instruction.microcode[i]=NOP;
}
}
}
break;
// invokevirtual
case 182:
if (r <= 3) x = 0;
else x = r-3;
if (r <= 2) y = 0;
else y = r-2;
for(int i=0;i<instruction.microcode.length;i++){
if(i<=5) instruction.microcode[i]=NOP;
else if(i==6) instruction.microcode[i]=RD;
else if(i>=7 && i<=31+r) instruction.microcode[i]=NOP;
else if(i==32+r) instruction.microcode[i]=RD;
else if(i>=33+r && i<=40+2*r) instruction.microcode[i]=NOP;
else if(i==41+2*r) instruction.microcode[i]=RD;
else if(i>=42+2*r && i<=52+2*r+x) instruction.microcode[i]=NOP;
else if(i==53+2*r+x) instruction.microcode[i]=RD;
else if(i>=54+2*r+x && i<=63+2*r+x+y) instruction.microcode[i]=NOP;
else{
if (pmiss == false || n==0)
instruction.microcode[i]=NOP;
else{
if (pmiss == false)
instruction.microcode[i]=NOP;
else{
if (cnt<(2+c())*(n+1)){
if (cnt % (r+1) == 0){
instruction.microcode[i]=RD;
cnt++;}
else{
instruction.microcode[i]=NOP;
cnt++;}
}
else
instruction.microcode[i]=NOP;
}
}
}
}
break;
// invokespecial, invokestatic
case 183:
case 184:
if (r <= 3) x = 0;
else x = r-3;
if (r <= 2) y = 0;
else y = r-2;
for(int i=0;i<instruction.microcode.length;i++){
if(i<=5) instruction.microcode[i]=NOP;
else if(i==6) instruction.microcode[i]=RD;
else if(i>=7 && i<=16+r) instruction.microcode[i]=NOP;
else if(i==17+r) instruction.microcode[i]=RD;
else if(i>=18+r && i<=28+r+x) instruction.microcode[i]=NOP;
else if(i==29+r+x) instruction.microcode[i]=RD;
else if(i>=30+r+x && i<=39+r+x+y) instruction.microcode[i]=NOP;
else{
if (pmiss == false || n==0)
instruction.microcode[i]=NOP;
else{
if (cnt<(2+c())*(n+1)){
if (cnt % (r+1) == 0){
instruction.microcode[i]=RD;
cnt++;}
else{
instruction.microcode[i]=NOP;
cnt++;}
}
else
instruction.microcode[i]=NOP;
}
}
}
break;
// invokeinterface
case 185:
break;
default:
}
}
// calculates WCET of instruction
public int wcetOfInstruction(int [] microcode){
int i = 0;
int j = 0;
int wcet=0;
int exec = 0;
int arb_period = getArbiterPeriod();
for(i=0;i<arb_period;i++){
exec = calcExecTime(i,microcode);
if (wcet<exec){
wcet = exec;
j = i;
}
}
//System.out.println("WCET: " + wcet + " Arbitration position: " + j);
return wcet;
}
// Calculates execution time of instruction, starting at a certain position of the
// arbitration period
public int calcExecTime(int arb_position, int [] microcode){
int arb_period = getArbiterPeriod();
int i=0;
int exec_time=0;
for(i=0;i<microcode.length;i++){
switch(microcode[i])
{
case NOP:
exec_time++;
arb_position++;
//System.out.println("NOP: " + exec_time);
break;
case RD:
while( (arbiter[arb_position]==false) ||
(((arb_position % arb_period ) >=timeslot-r) &&
((arb_position % arb_period ) <=timeslot)) ){
exec_time++;
arb_position++;
//System.out.println("Blocking RD: " + exec_time);
}
if(arbiter[arb_position]==true){
exec_time++;
arb_position++;
//System.out.println("RD: " + exec_time);
}
break;
case WR:
while( (arbiter[arb_position]==false) ||
(((arb_position % arb_period)>=timeslot-w) &&
((arb_position % arb_period)<=timeslot)) ){
exec_time++;
arb_position++;
}
if(arbiter[arb_position]==true){
exec_time++;
arb_position++;
}
break;
}
}
return exec_time;
}
/* Useful for cache analysis */
private static final int _HIDDEN_LOAD_CYCLES[][] =
{ { org.apache.bcel.Constants.IRETURN, IRETURN_HIDDEN_LOAD_CYCLES },
{ org.apache.bcel.Constants.FRETURN, FRETURN_HIDDEN_LOAD_CYCLES },
{ org.apache.bcel.Constants.LRETURN, LRETURN_HIDDEN_LOAD_CYCLES },
{ org.apache.bcel.Constants.DRETURN, DRETURN_HIDDEN_LOAD_CYCLES },
{ org.apache.bcel.Constants.ARETURN, ARETURN_HIDDEN_LOAD_CYCLES },
{ org.apache.bcel.Constants.RETURN, RETURN_HIDDEN_LOAD_CYCLES },
{ org.apache.bcel.Constants.INVOKEVIRTUAL, INVOKE_HIDDEN_LOAD_CYCLES },
{ org.apache.bcel.Constants.INVOKESPECIAL, INVOKE_HIDDEN_LOAD_CYCLES },
{ org.apache.bcel.Constants.INVOKESTATIC, INVOKE_HIDDEN_LOAD_CYCLES },
{ org.apache.bcel.Constants.INVOKEINTERFACE, INVOKE_HIDDEN_LOAD_CYCLES },
};
/** Hidden load cycles for invoke/return instructions */
public static final Map<Integer,Integer> HIDDEN_LOAD_CYCLES = asHashMap(_HIDDEN_LOAD_CYCLES);
private static Map<Integer, Integer> asHashMap(int[][] assocArray) {
HashMap<Integer, Integer> map = new HashMap<Integer,Integer>();
for(int[] entry : assocArray) {
map.put(entry[0], entry[1]);
}
return map;
}
}