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.regalloc.ia32; 014 015import static org.jikesrvm.compilers.opt.ir.Operators.IR_PROLOGUE; 016import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_ADDSD_opcode; 017import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_ADDSS_opcode; 018import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_ANDNPD_opcode; 019import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_ANDNPS_opcode; 020import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_ANDPD_opcode; 021import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_ANDPS_opcode; 022import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_BT_opcode; 023import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_CMOV_opcode; 024import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_CMPEQSD_opcode; 025import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_CMPEQSS_opcode; 026import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_CMPLESD_opcode; 027import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_CMPLESS_opcode; 028import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_CMPLTSD_opcode; 029import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_CMPLTSS_opcode; 030import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_CMPNESD_opcode; 031import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_CMPNESS_opcode; 032import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_CMPNLESD_opcode; 033import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_CMPNLESS_opcode; 034import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_CMPNLTSD_opcode; 035import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_CMPNLTSS_opcode; 036import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_CMPORDSD_opcode; 037import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_CMPORDSS_opcode; 038import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_CMPUNORDSD_opcode; 039import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_CMPUNORDSS_opcode; 040import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_CVTSD2SI_opcode; 041import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_CVTSD2SS_opcode; 042import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_CVTSI2SD_opcode; 043import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_CVTSI2SS_opcode; 044import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_CVTSS2SD_opcode; 045import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_CVTSS2SI_opcode; 046import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_CVTTSD2SI_opcode; 047import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_CVTTSS2SI_opcode; 048import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_DIVSD_opcode; 049import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_DIVSS_opcode; 050import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_FCLEAR; 051import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_FCMOV_opcode; 052import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_FCOMIP_opcode; 053import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_FCOMI_opcode; 054import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_FNINIT; 055import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_IMUL2_opcode; 056import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_MOVD_opcode; 057import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_MOVSXQ__B_opcode; 058import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_MOVSXQ__W_opcode; 059import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_MOVSX__B_opcode; 060import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_MOVSX__W_opcode; 061import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_MOVZXQ__B_opcode; 062import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_MOVZXQ__W_opcode; 063import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_MOVZX__B_opcode; 064import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_MOVZX__W_opcode; 065import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_MULSD_opcode; 066import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_MULSS_opcode; 067import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_ORPD_opcode; 068import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_ORPS_opcode; 069import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_PREFETCHNTA_opcode; 070import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_SET__B_opcode; 071import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_SHLD_opcode; 072import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_SHRD_opcode; 073import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_SQRTSD_opcode; 074import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_SQRTSS_opcode; 075import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_SUBSD_opcode; 076import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_SUBSS_opcode; 077import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_TEST_opcode; 078import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_UCOMISD_opcode; 079import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_UCOMISS_opcode; 080import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_XORPD_opcode; 081import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IA32_XORPS_opcode; 082import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.IMMQ_MOV_opcode; 083import static org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.MIR_LOWTABLESWITCH_opcode; 084import static org.jikesrvm.ia32.RegisterConstants.NUM_FPRS; 085 086import java.util.ArrayList; 087import java.util.Enumeration; 088 089import org.jikesrvm.VM; 090import org.jikesrvm.compilers.opt.ir.BasicBlock; 091import org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet; 092import org.jikesrvm.compilers.opt.ir.Instruction; 093import org.jikesrvm.compilers.opt.ir.Register; 094import org.jikesrvm.compilers.opt.ir.ia32.MIR_BinaryAcc; 095import org.jikesrvm.compilers.opt.ir.ia32.MIR_CacheOp; 096import org.jikesrvm.compilers.opt.ir.ia32.MIR_Compare; 097import org.jikesrvm.compilers.opt.ir.ia32.MIR_CondMove; 098import org.jikesrvm.compilers.opt.ir.ia32.MIR_DoubleShift; 099import org.jikesrvm.compilers.opt.ir.ia32.MIR_LowTableSwitch; 100import org.jikesrvm.compilers.opt.ir.ia32.MIR_Move; 101import org.jikesrvm.compilers.opt.ir.ia32.MIR_Set; 102import org.jikesrvm.compilers.opt.ir.ia32.MIR_Test; 103import org.jikesrvm.compilers.opt.ir.ia32.MIR_Unary; 104import org.jikesrvm.compilers.opt.ir.ia32.MIR_UnaryNoRes; 105import org.jikesrvm.compilers.opt.ir.ia32.PhysicalRegisterSet; 106import org.jikesrvm.compilers.opt.ir.operand.MemoryOperand; 107import org.jikesrvm.compilers.opt.ir.operand.Operand; 108import org.jikesrvm.compilers.opt.ir.operand.RegisterOperand; 109import org.jikesrvm.compilers.opt.ir.operand.ia32.BURSManagedFPROperand; 110import org.jikesrvm.compilers.opt.regalloc.GenericRegisterRestrictions; 111import org.jikesrvm.compilers.opt.regalloc.LiveIntervalElement; 112 113/** 114 * An instance of this class encapsulates restrictions on register 115 * assignment. 116 */ 117public final class RegisterRestrictions extends GenericRegisterRestrictions { 118 119 /** 120 * Allow scratch registers in PEIs? 121 */ 122 public static final boolean SCRATCH_IN_PEI = true; 123 124 public RegisterRestrictions(GenericPhysicalRegisterSet phys) { 125 super(phys); 126 } 127 128 @Override 129 public void addArchRestrictions(BasicBlock bb, ArrayList<LiveIntervalElement> symbolics) { 130 // If there are any registers used in catch blocks, we want to ensure 131 // that these registers are not used or evicted from scratch registers 132 // at a relevant PEI, so that the assumptions of register homes in the 133 // catch block remain valid. For now, we do this by forcing any 134 // register used in such a PEI as not spilled. TODO: relax this 135 // restriction for better code. 136 for (Enumeration<Instruction> ie = bb.forwardInstrEnumerator(); ie.hasMoreElements();) { 137 Instruction s = ie.nextElement(); 138 if (s.isPEI() && s.operator() != IR_PROLOGUE) { 139 if (bb.hasApplicableExceptionalOut(s) || !SCRATCH_IN_PEI) { 140 for (Enumeration<Operand> e = s.getOperands(); e.hasMoreElements();) { 141 Operand op = e.nextElement(); 142 if (op != null && op.isRegister()) { 143 noteMustNotSpill(op.asRegister().getRegister()); 144 handle8BitRestrictions(s); 145 } 146 } 147 } 148 } 149 150 // handle special cases 151 switch (s.getOpcode()) { 152 case MIR_LOWTABLESWITCH_opcode: { 153 RegisterOperand op = MIR_LowTableSwitch.getMethodStart(s); 154 noteMustNotSpill(op.getRegister()); 155 op = MIR_LowTableSwitch.getIndex(s); 156 noteMustNotSpill(op.getRegister()); 157 } 158 break; 159 case IA32_MOVZX__B_opcode: 160 case IA32_MOVSX__B_opcode: 161 case IA32_MOVZXQ__B_opcode: 162 case IA32_MOVSXQ__B_opcode: { 163 if (MIR_Unary.getVal(s).isRegister()) { 164 RegisterOperand val = MIR_Unary.getVal(s).asRegister(); 165 restrictTo8Bits(val.getRegister()); 166 } 167 } 168 break; 169 case IA32_SET__B_opcode: { 170 if (MIR_Set.getResult(s).isRegister()) { 171 RegisterOperand op = MIR_Set.getResult(s).asRegister(); 172 restrictTo8Bits(op.getRegister()); 173 } 174 } 175 break; 176 177 default: 178 handle8BitRestrictions(s); 179 break; 180 } 181 } 182 for (Enumeration<Instruction> ie = bb.forwardInstrEnumerator(); ie.hasMoreElements();) { 183 Instruction s = ie.nextElement(); 184 if (s.operator() == IA32_FNINIT) { 185 // No floating point register survives across an FNINIT 186 for (LiveIntervalElement symb : symbolics) { 187 if (symb.getRegister().isFloatingPoint()) { 188 if (contains(symb, regAllocState.getDFN(s))) { 189 addRestrictions(symb.getRegister(), phys.asIA32().getFPRs()); 190 } 191 } 192 } 193 } else if (s.operator() == IA32_FCLEAR) { 194 // Only some FPRs survive across an FCLEAR 195 for (LiveIntervalElement symb : symbolics) { 196 if (symb.getRegister().isFloatingPoint()) { 197 if (contains(symb, regAllocState.getDFN(s))) { 198 int nSave = MIR_UnaryNoRes.getVal(s).asIntConstant().value; 199 for (int i = nSave; i < NUM_FPRS; i++) { 200 addRestriction(symb.getRegister(), phys.getFPR(i)); 201 } 202 } 203 } 204 } 205 } 206 } 207 } 208 209 /** 210 * @param s the instruction to check 211 * @return {@code true} if and only if the instruction contains an 8-bit memory operand 212 */ 213 boolean has8BitMemoryOperand(Instruction s) { 214 for (Enumeration<Operand> me = s.getMemoryOperands(); me.hasMoreElements();) { 215 MemoryOperand mop = (MemoryOperand) me.nextElement(); 216 if (mop.size == 1) { 217 return true; 218 } 219 } 220 return false; 221 } 222 223 /** 224 * Ensure that if an operand has an 8 bit memory operand that 225 * all of its register operands are in 8 bit registers. 226 * @param s the instruction to restrict 227 */ 228 void handle8BitRestrictions(Instruction s) { 229 for (Enumeration<Operand> me = s.getMemoryOperands(); me.hasMoreElements();) { 230 MemoryOperand mop = (MemoryOperand) me.nextElement(); 231 if (mop.size == 1) { 232 for (Enumeration<Operand> e2 = s.getRootOperands(); e2.hasMoreElements();) { 233 Operand rootOp = e2.nextElement(); 234 if (rootOp.isRegister()) { 235 restrictTo8Bits(rootOp.asRegister().getRegister()); 236 } 237 } 238 } 239 } 240 } 241 242 /** 243 * Ensures that a particular register is only assigned to AL, BL, CL, or 244 * DL, since these are the only 8-bit registers we normally address. 245 * 246 * @param r the register that needs to be restricted to 8 bits 247 */ 248 void restrictTo8Bits(Register r) { 249 PhysicalRegisterSet phys = (PhysicalRegisterSet)this.phys; 250 Register ESP = phys.getESP(); 251 Register EBP = phys.getEBP(); 252 Register ESI = phys.getESI(); 253 Register EDI = phys.getEDI(); 254 addRestriction(r, ESP); 255 addRestriction(r, EBP); 256 addRestriction(r, ESI); 257 addRestriction(r, EDI); 258 } 259 260 /** 261 * Given symbolic register r that appears in instruction s, does the 262 * architecture demand that r be assigned to a physical register in s? 263 * 264 * @param r a symbolic register 265 * @param s instruction where the register appears 266 * 267 * @return {@code true} if the symbolic register r must use a physical 268 * register in the instruction, {@code false} if we can use a spill location 269 */ 270 public static boolean mustBeInRegister(Register r, Instruction s) { 271 switch (s.getOpcode()) { 272 case IA32_PREFETCHNTA_opcode: { 273 RegisterOperand op = MIR_CacheOp.getAddress(s).asRegister(); 274 if (op.getRegister() == r) return true; 275 } 276 break; 277 278 case IA32_SQRTSS_opcode: 279 case IA32_SQRTSD_opcode: 280 case IA32_CVTSD2SI_opcode: 281 case IA32_CVTSD2SS_opcode: 282 case IA32_CVTSI2SD_opcode: 283 case IA32_CVTSS2SD_opcode: 284 case IA32_CVTSS2SI_opcode: 285 case IA32_CVTTSD2SI_opcode: 286 case IA32_CVTTSS2SI_opcode: 287 case IA32_CVTSI2SS_opcode: { 288 RegisterOperand op = MIR_Unary.getResult(s).asRegister(); 289 if (op.getRegister() == r) return true; 290 } 291 break; 292 293 // Instructions that require 16byte alignment (not guaranteed by our 294 // spills) must be forced to always use registers 295 case IA32_ANDPS_opcode: 296 case IA32_ANDNPS_opcode: 297 case IA32_ORPS_opcode: 298 case IA32_XORPS_opcode: 299 case IA32_ANDPD_opcode: 300 case IA32_ANDNPD_opcode: 301 case IA32_ORPD_opcode: 302 case IA32_XORPD_opcode: 303 case IMMQ_MOV_opcode: 304 return true; 305 306 case IA32_ADDSS_opcode: 307 case IA32_CMPEQSS_opcode: 308 case IA32_CMPLTSS_opcode: 309 case IA32_CMPLESS_opcode: 310 case IA32_CMPUNORDSS_opcode: 311 case IA32_CMPNESS_opcode: 312 case IA32_CMPNLTSS_opcode: 313 case IA32_CMPNLESS_opcode: 314 case IA32_CMPORDSS_opcode: 315 case IA32_DIVSS_opcode: 316 case IA32_MULSS_opcode: 317 case IA32_SUBSS_opcode: 318 case IA32_ADDSD_opcode: 319 case IA32_CMPEQSD_opcode: 320 case IA32_CMPLTSD_opcode: 321 case IA32_CMPLESD_opcode: 322 case IA32_CMPUNORDSD_opcode: 323 case IA32_CMPNESD_opcode: 324 case IA32_CMPNLTSD_opcode: 325 case IA32_CMPNLESD_opcode: 326 case IA32_CMPORDSD_opcode: 327 case IA32_DIVSD_opcode: 328 case IA32_MULSD_opcode: 329 case IA32_SUBSD_opcode: { 330 RegisterOperand op = MIR_BinaryAcc.getResult(s).asRegister(); 331 if (op.getRegister() == r) return true; 332 } 333 break; 334 335 case IA32_UCOMISD_opcode: 336 case IA32_UCOMISS_opcode: { 337 RegisterOperand op = MIR_Compare.getVal1(s).asRegister(); 338 if (op.getRegister() == r) return true; 339 } 340 break; 341 342 case IA32_SHRD_opcode: 343 case IA32_SHLD_opcode: { 344 RegisterOperand op = MIR_DoubleShift.getSource(s); 345 if (op.getRegister() == r) return true; 346 } 347 break; 348 case IA32_FCOMI_opcode: 349 case IA32_FCOMIP_opcode: { 350 Operand op = MIR_Compare.getVal2(s); 351 if (!(op instanceof BURSManagedFPROperand)) { 352 if (op.asRegister().getRegister() == r) return true; 353 } 354 } 355 break; 356 case IA32_IMUL2_opcode: { 357 RegisterOperand op = MIR_BinaryAcc.getResult(s).asRegister(); 358 if (op.getRegister() == r) return true; 359 } 360 break; 361 case MIR_LOWTABLESWITCH_opcode: { 362 RegisterOperand op = MIR_LowTableSwitch.getIndex(s); 363 if (op.getRegister() == r) return true; 364 } 365 break; 366 case IA32_CMOV_opcode: 367 case IA32_FCMOV_opcode: { 368 RegisterOperand op = MIR_CondMove.getResult(s).asRegister(); 369 if (op.getRegister() == r) return true; 370 } 371 break; 372 case IA32_MOVD_opcode: { 373 RegisterOperand res = MIR_Move.getResult(s).asRegister(); 374 if (!res.isFloat() && !res.isDouble()) { 375 // result is integer so source must be MM/XMM register and 376 // result must remain a register 377 if (VM.VerifyAssertions) { 378 Operand val = MIR_Move.getValue(s); 379 VM._assert(val.isRegister() && (val.isFloat() || val.isDouble())); 380 } 381 return true; 382 } 383 Operand val = MIR_Move.getValue(s); 384 if (!val.isFloat() && !val.isDouble()) { 385 // source is integer so destination must be MM/XMM register and 386 // source must remain a register 387 if (VM.VerifyAssertions) { 388 VM._assert(res.isRegister() && (res.isFloat() || res.isDouble())); 389 } 390 return true; 391 } 392 } 393 break; 394 case IA32_MOVZX__B_opcode: 395 case IA32_MOVSX__B_opcode: 396 case IA32_MOVZXQ__B_opcode: 397 case IA32_MOVSXQ__B_opcode: { 398 RegisterOperand op = MIR_Unary.getResult(s).asRegister(); 399 if (op.getRegister() == r) return true; 400 } 401 break; 402 case IA32_MOVZX__W_opcode: 403 case IA32_MOVSX__W_opcode: 404 case IA32_MOVZXQ__W_opcode: 405 case IA32_MOVSXQ__W_opcode: { 406 RegisterOperand op = MIR_Unary.getResult(s).asRegister(); 407 if (op.getRegister() == r) return true; 408 } 409 break; 410 case IA32_SET__B_opcode: { 411 if (MIR_Set.getResult(s).isRegister()) { 412 RegisterOperand op = MIR_Set.getResult(s).asRegister(); 413 if (op.asRegister().getRegister() == r) return true; 414 } 415 } 416 break; 417 case IA32_TEST_opcode: { 418 // at least 1 of the two operands must be in a register 419 if (!MIR_Test.getVal2(s).isConstant()) { 420 if (MIR_Test.getVal1(s).isRegister()) { 421 if (MIR_Test.getVal1(s).asRegister().getRegister() == r) return true; 422 } else if (MIR_Test.getVal2(s).isRegister()) { 423 if (MIR_Test.getVal2(s).asRegister().getRegister() == r) return true; 424 } 425 } 426 } 427 break; 428 case IA32_BT_opcode: { 429 // val2 of bit test must be either a constant or register 430 if (!MIR_Test.getVal2(s).isConstant()) { 431 if (MIR_Test.getVal2(s).isRegister()) { 432 if (MIR_Test.getVal2(s).asRegister().getRegister() == r) return true; 433 } 434 } 435 } 436 break; 437 438 default: 439 break; 440 } 441 return false; 442 } 443 444 /** 445 * @param r the register to check 446 * @return {@code true} if the physical register r hold an 8-bit value? 447 */ 448 private boolean okFor8(Register r) { 449 PhysicalRegisterSet phys = (PhysicalRegisterSet)this.phys; 450 Register ESP = phys.getESP(); 451 Register EBP = phys.getEBP(); 452 Register ESI = phys.getESI(); 453 Register EDI = phys.getEDI(); 454 return (r != ESP && r != EBP && r != ESI && r != EDI); 455 } 456 457 @Override 458 public boolean isForbidden(Register symb, Register r, Instruction s) { 459 460 // Look at 8-bit restrictions. 461 switch (s.getOpcode()) { 462 case IA32_MOVZX__B_opcode: 463 case IA32_MOVSX__B_opcode: 464 case IA32_MOVZXQ__B_opcode: 465 case IA32_MOVSXQ__B_opcode: { 466 if (MIR_Unary.getVal(s).isRegister()) { 467 RegisterOperand val = MIR_Unary.getVal(s).asRegister(); 468 if (val.getRegister() == symb) { 469 return !okFor8(r); 470 } 471 } 472 } 473 break; 474 case IA32_SET__B_opcode: { 475 if (MIR_Set.getResult(s).isRegister()) { 476 RegisterOperand op = MIR_Set.getResult(s).asRegister(); 477 if (op.asRegister().getRegister() == symb) { 478 return !okFor8(r); 479 } 480 } 481 } 482 break; 483 } 484 485 if (has8BitMemoryOperand(s)) { 486 return !okFor8(r); 487 } 488 489 // Otherwise, it's OK. 490 return false; 491 } 492}