001/* 002 * This file is part of the Jikes RVM project (http://jikesrvm.org). 003 * 004 * This file is licensed to You under the Eclipse Public License (EPL); 005 * You may not use this file except in compliance with the License. You 006 * may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/eclipse-1.0.php 009 * 010 * See the COPYRIGHT.txt file distributed with this work for information 011 * regarding copyright ownership. 012 */ 013package org.jikesrvm.compilers.opt.lir2mir; 014 015import org.jikesrvm.*; 016import org.jikesrvm.compilers.opt.depgraph.DepGraphNode; 017import org.jikesrvm.compilers.opt.ir.*; 018 019/** 020 * An AbstractBURS_TreeNode is a node in a binary tree that is fed 021 * as input to BURS. Machine generated versions are created for 022 * every architecture and address size. 023 * 024 * @see BURS 025 * @see BURS_StateCoder 026 */ 027public abstract class AbstractBURS_TreeNode { 028 029 AbstractBURS_TreeNode child1; 030 AbstractBURS_TreeNode child2; 031 032 /** 033 * Dependence graph node corresponding to 034 * interior node in BURS tree (set to null for 035 * leaf node or for OTHER_OPERAND node). 036 */ 037 public final DepGraphNode dg_node; 038 039 /** 040 * Opcode of instruction 041 */ 042 private final char opcode; 043 044 /** 045 * nonterminal > 0 ==> this tree node is the 046 * root of a "supernode"; the value of nonterminal 047 * identifies the matching non-terminal 048 * nonterminal = 0 ==> this tree node is NOT the 049 * root of a "supernode". 050 */ 051 private byte nonterminal; 052 053 /** 054 * <pre> 055 * trrr rrrr 056 * t = tree root 057 * r = num of registers used 058 * </pre> 059 */ 060 private byte treeroot_registersused; 061 062 public final char getOpcode() { 063 return opcode; 064 } 065 066 public final AbstractBURS_TreeNode getChild1() { 067 return child1; 068 } 069 070 public final void setChild1(AbstractBURS_TreeNode x) { 071 child1 = x; 072 } 073 074 public final AbstractBURS_TreeNode getChild2() { 075 return child2; 076 } 077 078 public final void setChild2(AbstractBURS_TreeNode x) { 079 child2 = x; 080 } 081 082 public final int getNonTerminal() { 083 return nonterminal & 0xFF; 084 } 085 086 public final void setNonTerminal(int nonterminal) { 087 if (VM.VerifyAssertions) VM._assert(nonterminal <= 0xff); 088 this.nonterminal = (byte)nonterminal; 089 } 090 091 public final boolean isTreeRoot() { 092 return (treeroot_registersused & 0x80) != 0; 093 } 094 095 public final void setTreeRoot() { 096 treeroot_registersused |= 0x80; 097 } 098 099 public final void setNumRegisters(int r) { 100 treeroot_registersused = (byte)((treeroot_registersused & 0x80) | (r & 0x7f)); 101 } 102 public final int numRegisters() { 103 return treeroot_registersused & 0x7f; 104 } 105 106 public final Instruction getInstruction() { 107 return dg_node._instr; 108 } 109 110 public final String getInstructionString() { 111 if (dg_node != null) { 112 return dg_node._instr.toString(); 113 } else { 114 return ""; 115 } 116 } 117 118 /** 119 * Constructor for interior node. 120 * @param n the dep graph node 121 */ 122 protected AbstractBURS_TreeNode(DepGraphNode n) { 123 Instruction instr = n._instr; 124 dg_node = n; 125 opcode = instr.getOpcode(); 126 } 127 128 129 /** 130 * @param n the dep graph node 131 * @return an interior node 132 */ 133 public static AbstractBURS_TreeNode create(DepGraphNode n) { 134 if (VM.BuildForIA32) { 135 if (VM.BuildFor32Addr) { 136 return new org.jikesrvm.compilers.opt.lir2mir.ia32_32.BURS_TreeNode(n); 137 } else { 138 return new org.jikesrvm.compilers.opt.lir2mir.ia32_64.BURS_TreeNode(n); 139 } 140 } else { 141 if (VM.VerifyAssertions) VM._assert(VM.BuildForPowerPC); 142 if (VM.BuildFor32Addr) { 143 return new org.jikesrvm.compilers.opt.lir2mir.ppc_32.BURS_TreeNode(n); 144 } else { 145 return new org.jikesrvm.compilers.opt.lir2mir.ppc_64.BURS_TreeNode(n); 146 } 147 } 148 } 149 150 /** 151 * Constructor for leaf/auxiliary node. 152 * @param Opcode the opcode for the node 153 */ 154 protected AbstractBURS_TreeNode(char Opcode) { 155 dg_node = null; 156 opcode = Opcode; 157 } 158 159 /** 160 * @param Opcode the node's opcode 161 * @return a leaf/auxiliary node. 162 */ 163 public static AbstractBURS_TreeNode create(char Opcode) { 164 if (VM.BuildForIA32) { 165 if (VM.BuildFor32Addr) { 166 return new org.jikesrvm.compilers.opt.lir2mir.ia32_32.BURS_TreeNode(Opcode); 167 } else { 168 return new org.jikesrvm.compilers.opt.lir2mir.ia32_64.BURS_TreeNode(Opcode); 169 } 170 } else { 171 if (VM.VerifyAssertions) VM._assert(VM.BuildForPowerPC); 172 if (VM.BuildFor32Addr) { 173 return new org.jikesrvm.compilers.opt.lir2mir.ppc_32.BURS_TreeNode(Opcode); 174 } else { 175 return new org.jikesrvm.compilers.opt.lir2mir.ppc_64.BURS_TreeNode(Opcode); 176 } 177 } 178 } 179 180 @Override 181 public String toString() { 182 return Operator.lookupOpcode(getOpcode()).toString(); 183 } 184 185 public final boolean isSuperNodeRoot() { 186 return (getNonTerminal() > 0); 187 } 188 189 public final boolean isREGISTERNode() { 190 return getOpcode() == Operators.REGISTER_opcode; 191 } 192 193 /** 194 * Get the BURS rule number associated with this tree node for a given non-terminal 195 * 196 * @param goalNT the non-terminal we want to know the rule for (e.g. stm_NT) 197 * @return the rule number 198 */ 199 public abstract int rule(int goalNT); 200 201 public abstract char getCost(int goalNT); 202 203 public abstract void setCost(int goalNT, char cost); 204 205 public abstract void initCost(); 206 207 public abstract void writePacked(int word, int mask, int shiftedValue); 208 209 public abstract int readPacked(int word, int shift, int mask); 210}