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}