Use .size and .type on ELF systems; this helps tools that map
[oota-llvm.git] / lib / Target / ARM / ARMCodeEmitter.cpp
index d6d98148818f2652be0488e626b1fb3c29a18411..c27fc5f1eafff4d3edf52f82d3a539030c8a57f0 100644 (file)
@@ -83,6 +83,8 @@ namespace {
 
     void emitLEApcrelJTInstruction(const MachineInstr &MI);
 
+    void emitPseudoMoveInstruction(const MachineInstr &MI);
+
     void addPCLabel(unsigned LabelID);
 
     void emitPseudoInstruction(const MachineInstr &MI);
@@ -302,9 +304,10 @@ void ARMCodeEmitter::emitInstruction(const MachineInstr &MI) {
 
   NumEmitted++;  // Keep track of the # of mi's emitted
   switch (MI.getDesc().TSFlags & ARMII::FormMask) {
-  default:
+  default: {
     assert(0 && "Unhandled instruction encoding format!");
     break;
+  }
   case ARMII::Pseudo:
     emitPseudoInstruction(MI);
     break;
@@ -320,8 +323,7 @@ void ARMCodeEmitter::emitInstruction(const MachineInstr &MI) {
   case ARMII::StMiscFrm:
     emitMiscLoadStoreInstruction(MI);
     break;
-  case ARMII::LdMulFrm:
-  case ARMII::StMulFrm:
+  case ARMII::LdStMulFrm:
     emitLoadStoreMultipleInstruction(MI);
     break;
   case ARMII::MulFrm:
@@ -347,6 +349,8 @@ void ARMCodeEmitter::emitInstruction(const MachineInstr &MI) {
   case ARMII::VFPConv1Frm:
   case ARMII::VFPConv2Frm:
   case ARMII::VFPConv3Frm:
+  case ARMII::VFPConv4Frm:
+  case ARMII::VFPConv5Frm:
     emitVFPConversionInstruction(MI);
     break;
   case ARMII::VFPLdStFrm:
@@ -387,7 +391,7 @@ void ARMCodeEmitter::emitConstPoolInstruction(const MachineInstr &MI) {
                   (intptr_t)ACPV, false));
       else 
         emitGlobalAddress(GV, ARM::reloc_arm_machine_cp_entry,
-                          ACPV->isStub(), (intptr_t)ACPV);
+                          ACPV->isStub() || isa<Function>(GV), (intptr_t)ACPV);
      } else  {
       assert(!ACPV->isNonLazyPointer() && "Don't know how to deal this yet!");
       emitExternalSymbolAddress(ACPV->getSymbol(), ARM::reloc_arm_absolute);
@@ -396,11 +400,18 @@ void ARMCodeEmitter::emitConstPoolInstruction(const MachineInstr &MI) {
   } else {
     Constant *CV = MCPE.Val.ConstVal;
 
+#ifndef NDEBUG
     DOUT << "  ** Constant pool #" << CPI << " @ "
-         << (void*)MCE.getCurrentPCValue() << " " << *CV << '\n';
+         << (void*)MCE.getCurrentPCValue() << " ";
+    if (const Function *F = dyn_cast<Function>(CV))
+      DOUT << F->getName();
+    else
+      DOUT << *CV;
+    DOUT << '\n';
+#endif
 
     if (GlobalValue *GV = dyn_cast<GlobalValue>(CV)) {
-      emitGlobalAddress(GV, ARM::reloc_arm_absolute, false);
+      emitGlobalAddress(GV, ARM::reloc_arm_absolute, isa<Function>(GV));
       emitWordLE(0);
     } else if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
       uint32_t Val = *(uint32_t*)CI->getValue().getRawData();
@@ -490,6 +501,45 @@ void ARMCodeEmitter::emitLEApcrelJTInstruction(const MachineInstr &MI) {
   emitWordLE(Binary);
 }
 
+void ARMCodeEmitter::emitPseudoMoveInstruction(const MachineInstr &MI) {
+  unsigned Opcode = MI.getDesc().Opcode;
+
+  // Part of binary is determined by TableGn.
+  unsigned Binary = getBinaryCodeForInstr(MI);
+
+  // Set the conditional execution predicate
+  Binary |= II->getPredicate(&MI) << ARMII::CondShift;
+
+  // Encode S bit if MI modifies CPSR.
+  if (Opcode == ARM::MOVsrl_flag || Opcode == ARM::MOVsra_flag)
+    Binary |= 1 << ARMII::S_BitShift;
+
+  // Encode register def if there is one.
+  Binary |= getMachineOpValue(MI, 0) << ARMII::RegRdShift;
+
+  // Encode the shift operation.
+  switch (Opcode) {
+  default: break;
+  case ARM::MOVrx:
+    // rrx
+    Binary |= 0x6 << 4;
+    break;
+  case ARM::MOVsrl_flag:
+    // lsr #1
+    Binary |= (0x2 << 4) | (1 << 7);
+    break;
+  case ARM::MOVsra_flag:
+    // asr #1
+    Binary |= (0x4 << 4) | (1 << 7);
+    break;
+  }
+
+  // Encode register Rm.
+  Binary |= getMachineOpValue(MI, 1);
+
+  emitWordLE(Binary);
+}
+
 void ARMCodeEmitter::addPCLabel(unsigned LabelID) {
   DOUT << "  ** LPC" << LabelID << " @ "
        << (void*)MCE.getCurrentPCValue() << '\n';
@@ -501,6 +551,24 @@ void ARMCodeEmitter::emitPseudoInstruction(const MachineInstr &MI) {
   switch (Opcode) {
   default:
     abort(); // FIXME:
+  case TargetInstrInfo::INLINEASM: {
+    // We allow inline assembler nodes with empty bodies - they can
+    // implicitly define registers, which is ok for JIT.
+    if (MI.getOperand(0).getSymbolName()[0]) {
+      assert(0 && "JIT does not support inline asm!\n");
+      abort();
+    }
+    break;
+  }
+  case TargetInstrInfo::DBG_LABEL:
+  case TargetInstrInfo::EH_LABEL:
+    MCE.emitLabel(MI.getOperand(0).getImm());
+    break;
+  case TargetInstrInfo::IMPLICIT_DEF:
+  case TargetInstrInfo::DECLARE:
+  case ARM::DWARF_LOC:
+    // Do nothing.
+    break;
   case ARM::CONSTPOOL_ENTRY:
     emitConstPoolInstruction(MI);
     break;
@@ -539,6 +607,11 @@ void ARMCodeEmitter::emitPseudoInstruction(const MachineInstr &MI) {
     // Materialize jumptable address.
     emitLEApcrelJTInstruction(MI);
     break;
+  case ARM::MOVrx:
+  case ARM::MOVsrl_flag:
+  case ARM::MOVsra_flag:
+    emitPseudoMoveInstruction(MI);
+    break;
   }
 }
 
@@ -688,6 +761,8 @@ void ARMCodeEmitter::emitLoadStoreInstruction(const MachineInstr &MI,
                                               unsigned ImplicitRd,
                                               unsigned ImplicitRn) {
   const TargetInstrDesc &TID = MI.getDesc();
+  unsigned Form = TID.TSFlags & ARMII::FormMask;
+  bool IsPrePost = (TID.TSFlags & ARMII::IndexModeMask) != 0;
 
   // Part of binary is determined by TableGn.
   unsigned Binary = getBinaryCodeForInstr(MI);
@@ -695,8 +770,17 @@ void ARMCodeEmitter::emitLoadStoreInstruction(const MachineInstr &MI,
   // Set the conditional execution predicate
   Binary |= II->getPredicate(&MI) << ARMII::CondShift;
 
-  // Set first operand
   unsigned OpIdx = 0;
+
+  // Operand 0 of a pre- and post-indexed store is the address base
+  // writeback. Skip it.
+  bool Skipped = false;
+  if (IsPrePost && Form == ARMII::StFrm) {
+    ++OpIdx;
+    Skipped = true;
+  }
+
+  // Set first operand
   if (ImplicitRd)
     // Special handling for implicit use (e.g. PC).
     Binary |= (ARMRegisterInfo::getRegisterNumbering(ImplicitRd)
@@ -713,7 +797,7 @@ void ARMCodeEmitter::emitLoadStoreInstruction(const MachineInstr &MI,
     Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRnShift;
 
   // If this is a two-address operand, skip it. e.g. LDR_PRE.
-  if (TID.getOperandConstraint(OpIdx, TOI::TIED_TO) != -1)
+  if (!Skipped && TID.getOperandConstraint(OpIdx, TOI::TIED_TO) != -1)
     ++OpIdx;
 
   const MachineOperand &MO2 = MI.getOperand(OpIdx);
@@ -737,11 +821,11 @@ void ARMCodeEmitter::emitLoadStoreInstruction(const MachineInstr &MI,
   // Set bit[3:0] to the corresponding Rm register
   Binary |= ARMRegisterInfo::getRegisterNumbering(MO2.getReg());
 
-  // if this instr is in scaled register offset/index instruction, set
+  // If this instr is in scaled register offset/index instruction, set
   // shift_immed(bit[11:7]) and shift(bit[6:5]) fields.
   if (unsigned ShImm = ARM_AM::getAM2Offset(AM2Opc)) {
-    Binary |= getShiftOp(AM2Opc) << 5;  // shift
-    Binary |= ShImm              << 7;  // shift_immed
+    Binary |= getShiftOp(AM2Opc) << ARMII::ShiftImmShift;  // shift
+    Binary |= ShImm              << ARMII::ShiftShift;     // shift_immed
   }
 
   emitWordLE(Binary);
@@ -750,6 +834,8 @@ void ARMCodeEmitter::emitLoadStoreInstruction(const MachineInstr &MI,
 void ARMCodeEmitter::emitMiscLoadStoreInstruction(const MachineInstr &MI,
                                                   unsigned ImplicitRn) {
   const TargetInstrDesc &TID = MI.getDesc();
+  unsigned Form = TID.TSFlags & ARMII::FormMask;
+  bool IsPrePost = (TID.TSFlags & ARMII::IndexModeMask) != 0;
 
   // Part of binary is determined by TableGn.
   unsigned Binary = getBinaryCodeForInstr(MI);
@@ -757,11 +843,20 @@ void ARMCodeEmitter::emitMiscLoadStoreInstruction(const MachineInstr &MI,
   // Set the conditional execution predicate
   Binary |= II->getPredicate(&MI) << ARMII::CondShift;
 
+  unsigned OpIdx = 0;
+
+  // Operand 0 of a pre- and post-indexed store is the address base
+  // writeback. Skip it.
+  bool Skipped = false;
+  if (IsPrePost && Form == ARMII::StMiscFrm) {
+    ++OpIdx;
+    Skipped = true;
+  }
+
   // Set first operand
-  Binary |= getMachineOpValue(MI, 0) << ARMII::RegRdShift;
+  Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRdShift;
 
   // Set second operand
-  unsigned OpIdx = 1;
   if (ImplicitRn)
     // Special handling for implicit use (e.g. PC).
     Binary |= (ARMRegisterInfo::getRegisterNumbering(ImplicitRn)
@@ -770,7 +865,7 @@ void ARMCodeEmitter::emitMiscLoadStoreInstruction(const MachineInstr &MI,
     Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRnShift;
 
   // If this is a two-address operand, skip it. e.g. LDRH_POST.
-  if (TID.getOperandConstraint(OpIdx, TOI::TIED_TO) != -1)
+  if (!Skipped && TID.getOperandConstraint(OpIdx, TOI::TIED_TO) != -1)
     ++OpIdx;
 
   const MachineOperand &MO2 = MI.getOperand(OpIdx);
@@ -793,8 +888,8 @@ void ARMCodeEmitter::emitMiscLoadStoreInstruction(const MachineInstr &MI,
   Binary |= 1 << ARMII::AM3_I_BitShift;
   if (unsigned ImmOffs = ARM_AM::getAM3Offset(AM3Opc)) {
     // Set operands
-    Binary |= (ImmOffs >> 4) << 8;  // immedH
-    Binary |= (ImmOffs & ~0xF);     // immedL
+    Binary |= (ImmOffs >> 4) << ARMII::ImmHiShift;  // immedH
+    Binary |= (ImmOffs & 0xF);                      // immedL
   }
 
   emitWordLE(Binary);
@@ -983,7 +1078,7 @@ void ARMCodeEmitter::emitBranchInstruction(const MachineInstr &MI) {
 
 void ARMCodeEmitter::emitInlineJumpTable(unsigned JTIndex) {
   // Remember the base address of the inline jump table.
-  intptr_t JTBase = MCE.getCurrentPCValue();
+  uintptr_t JTBase = MCE.getCurrentPCValue();
   JTI->addJumpTableBaseAddr(JTIndex, JTBase);
   DOUT << "  ** Jump Table #" << JTIndex << " @ " << (void*)JTBase << '\n';
 
@@ -1038,6 +1133,48 @@ void ARMCodeEmitter::emitMiscBranchInstruction(const MachineInstr &MI) {
   emitWordLE(Binary);
 }
 
+static unsigned encodeVFPRd(const MachineInstr &MI, unsigned OpIdx) {
+  unsigned RegD = MI.getOperand(OpIdx).getReg();
+  unsigned Binary = 0;
+  bool isSPVFP = false;
+  RegD = ARMRegisterInfo::getRegisterNumbering(RegD, isSPVFP);
+  if (!isSPVFP)
+    Binary |=   RegD               << ARMII::RegRdShift;
+  else {
+    Binary |= ((RegD & 0x1E) >> 1) << ARMII::RegRdShift;
+    Binary |=  (RegD & 0x01)       << ARMII::D_BitShift;
+  }
+  return Binary;
+}
+
+static unsigned encodeVFPRn(const MachineInstr &MI, unsigned OpIdx) {
+  unsigned RegN = MI.getOperand(OpIdx).getReg();
+  unsigned Binary = 0;
+  bool isSPVFP = false;
+  RegN = ARMRegisterInfo::getRegisterNumbering(RegN, isSPVFP);
+  if (!isSPVFP)
+    Binary |=   RegN               << ARMII::RegRnShift;
+  else {
+    Binary |= ((RegN & 0x1E) >> 1) << ARMII::RegRnShift;
+    Binary |=  (RegN & 0x01)       << ARMII::N_BitShift;
+  }
+  return Binary;
+}
+
+static unsigned encodeVFPRm(const MachineInstr &MI, unsigned OpIdx) {
+  unsigned RegM = MI.getOperand(OpIdx).getReg();
+  unsigned Binary = 0;
+  bool isSPVFP = false;
+  RegM = ARMRegisterInfo::getRegisterNumbering(RegM, isSPVFP);
+  if (!isSPVFP)
+    Binary |=   RegM;
+  else {
+    Binary |= ((RegM & 0x1E) >> 1);
+    Binary |=  (RegM & 0x01)       << ARMII::M_BitShift;
+  }
+  return Binary;
+}
+
 void ARMCodeEmitter::emitVFPArithInstruction(const MachineInstr &MI) {
   const TargetInstrDesc &TID = MI.getDesc();
 
@@ -1053,50 +1190,33 @@ void ARMCodeEmitter::emitVFPArithInstruction(const MachineInstr &MI) {
          (Binary & ARMII::M_BitShift) == 0 && "VFP encoding bug!");
 
   // Encode Dd / Sd.
-  unsigned RegD = MI.getOperand(OpIdx++).getReg();
-  bool isSPVFP = false;
-  RegD = ARMRegisterInfo::getRegisterNumbering(RegD, isSPVFP);
-  if (!isSPVFP)
-    Binary |=   RegD               << ARMII::RegRdShift;
-  else {
-    Binary |= ((RegD & 0x1E) >> 1) << ARMII::RegRdShift;
-    Binary |=  (RegD & 0x01)       << ARMII::D_BitShift;
-  }
-    
+  Binary |= encodeVFPRd(MI, OpIdx++);
 
   // If this is a two-address operand, skip it, e.g. FMACD.
   if (TID.getOperandConstraint(OpIdx, TOI::TIED_TO) != -1)
     ++OpIdx;
 
   // Encode Dn / Sn.
-  if ((TID.TSFlags & ARMII::FormMask) == ARMII::VFPBinaryFrm) {
-    unsigned RegN = MI.getOperand(OpIdx++).getReg();
-    isSPVFP = false;
-    RegN = ARMRegisterInfo::getRegisterNumbering(RegN, isSPVFP);
-    if (!isSPVFP)
-      Binary |=   RegN               << ARMII::RegRnShift;
-    else {
-      Binary |= ((RegN & 0x1E) >> 1) << ARMII::RegRnShift;
-      Binary |=  (RegN & 0x01)       << ARMII::N_BitShift;
-    }
+  if ((TID.TSFlags & ARMII::FormMask) == ARMII::VFPBinaryFrm)
+    Binary |= encodeVFPRn(MI, OpIdx++);
+
+  if (OpIdx == TID.getNumOperands() ||
+      TID.OpInfo[OpIdx].isPredicate() ||
+      TID.OpInfo[OpIdx].isOptionalDef()) {
+    // FCMPEZD etc. has only one operand.
+    emitWordLE(Binary);
+    return;
   }
 
   // Encode Dm / Sm.
-  unsigned RegM = MI.getOperand(OpIdx++).getReg();
-  isSPVFP = false;
-  RegM = ARMRegisterInfo::getRegisterNumbering(RegM, isSPVFP);
-  if (!isSPVFP)
-    Binary |=   RegM;
-  else {
-    Binary |= ((RegM & 0x1E) >> 1);
-    Binary |=  (RegM & 0x01)       << ARMII::M_BitShift;
-  }
+  Binary |= encodeVFPRm(MI, OpIdx);
   
   emitWordLE(Binary);
 }
 
 void ARMCodeEmitter::emitVFPConversionInstruction(const MachineInstr &MI) {
   const TargetInstrDesc &TID = MI.getDesc();
+  unsigned Form = TID.TSFlags & ARMII::FormMask;
 
   // Part of binary is determined by TableGn.
   unsigned Binary = getBinaryCodeForInstr(MI);
@@ -1104,68 +1224,48 @@ void ARMCodeEmitter::emitVFPConversionInstruction(const MachineInstr &MI) {
   // Set the conditional execution predicate
   Binary |= II->getPredicate(&MI) << ARMII::CondShift;
 
-  // FMDRR encodes registers in reverse order.
-  unsigned Form = TID.TSFlags & ARMII::FormMask;
-  unsigned OpIdx = (Form == ARMII::VFPConv2Frm)
-    ? MI.findFirstPredOperandIdx()-1 : 0;
-
-  // Encode Dd / Sd.
-  unsigned RegD = MI.getOperand(OpIdx).getReg();
-  bool isSPVFP = false;
-  RegD = ARMRegisterInfo::getRegisterNumbering(RegD, isSPVFP);
-  if (!isSPVFP)
-    Binary |=   RegD               << ARMII::RegRdShift;
-  else {
-    Binary |= ((RegD & 0x1E) >> 1) << ARMII::RegRdShift;
-    Binary |=  (RegD & 0x01)       << ARMII::D_BitShift;
-  }
-  if (Form == ARMII::VFPConv2Frm)
-    --OpIdx;
-  else
-    ++OpIdx;
-
-  if (Form == ARMII::VFPConv3Frm) {
-    unsigned RegM = MI.getOperand(OpIdx).getReg();
-    isSPVFP = false;
-    RegM = ARMRegisterInfo::getRegisterNumbering(RegM, isSPVFP);
-    if (!isSPVFP)
-      Binary |=   RegM;
-    else {
-      Binary |= ((RegM & 0x1E) >> 1);
-      Binary |=  (RegM & 0x01)       << ARMII::M_BitShift;
-    }
-
-    emitWordLE(Binary);
-    return;
+  switch (Form) {
+  default: break;
+  case ARMII::VFPConv1Frm:
+  case ARMII::VFPConv2Frm:
+  case ARMII::VFPConv3Frm:
+    // Encode Dd / Sd.
+    Binary |= encodeVFPRd(MI, 0);
+    break;
+  case ARMII::VFPConv4Frm:
+    // Encode Dn / Sn.
+    Binary |= encodeVFPRn(MI, 0);
+    break;
+  case ARMII::VFPConv5Frm:
+    // Encode Dm / Sm.
+    Binary |= encodeVFPRm(MI, 0);
+    break;
   }
 
-  // Encode Dn / Sn.
-  unsigned RegN = MI.getOperand(OpIdx).getReg();
-  isSPVFP = false;
-  RegN = ARMRegisterInfo::getRegisterNumbering(RegN, isSPVFP);
-  if (!isSPVFP)
-    Binary |=   RegN               << ARMII::RegRnShift;
-  else {
-    Binary |= ((RegN & 0x1E) >> 1) << ARMII::RegRnShift;
-    Binary |=  (RegN & 0x01)       << ARMII::N_BitShift;
+  switch (Form) {
+  default: break;
+  case ARMII::VFPConv1Frm:
+    // Encode Dm / Sm.
+    Binary |= encodeVFPRm(MI, 1);
+    break;
+  case ARMII::VFPConv2Frm:
+  case ARMII::VFPConv3Frm:
+    // Encode Dn / Sn.
+    Binary |= encodeVFPRn(MI, 1);
+    break;
+  case ARMII::VFPConv4Frm:
+  case ARMII::VFPConv5Frm:
+    // Encode Dd / Sd.
+    Binary |= encodeVFPRd(MI, 1);
+    break;
   }
-  if (Form == ARMII::VFPConv2Frm)
-    --OpIdx;
-  else
-    ++OpIdx;
 
-  // FMRS / FMSR do not have Rm.
-  if (TID.getNumOperands() > OpIdx && MI.getOperand(OpIdx).isReg()) {
-    unsigned RegM = MI.getOperand(OpIdx).getReg();
-    isSPVFP = false;
-    RegM = ARMRegisterInfo::getRegisterNumbering(RegM, isSPVFP);
-    if (!isSPVFP)
-      Binary |=   RegM;
-    else {
-      Binary |= ((RegM & 0x1E) >> 1);
-      Binary |=  (RegM & 0x01)       << ARMII::M_BitShift;
-    }
-  }
+  if (Form == ARMII::VFPConv5Frm)
+    // Encode Dn / Sn.
+    Binary |= encodeVFPRn(MI, 2);
+  else if (Form == ARMII::VFPConv3Frm)
+    // Encode Dm / Sm.
+    Binary |= encodeVFPRm(MI, 2);
 
   emitWordLE(Binary);
 }
@@ -1180,15 +1280,7 @@ void ARMCodeEmitter::emitVFPLoadStoreInstruction(const MachineInstr &MI) {
   unsigned OpIdx = 0;
 
   // Encode Dd / Sd.
-  unsigned RegD = MI.getOperand(OpIdx++).getReg();
-  bool isSPVFP = false;
-  RegD = ARMRegisterInfo::getRegisterNumbering(RegD, isSPVFP);
-  if (!isSPVFP)
-    Binary |=   RegD               << ARMII::RegRdShift;
-  else {
-    Binary |= ((RegD & 0x1E) >> 1) << ARMII::RegRdShift;
-    Binary |=  (RegD & 0x01)       << ARMII::D_BitShift;
-  }
+  Binary |= encodeVFPRd(MI, OpIdx++);
 
   // Encode address base.
   const MachineOperand &Base = MI.getOperand(OpIdx++);
@@ -1200,8 +1292,7 @@ void ARMCodeEmitter::emitVFPLoadStoreInstruction(const MachineInstr &MI) {
     if (unsigned ImmOffs = ARM_AM::getAM5Offset(Offset.getImm())) {
       if (ARM_AM::getAM5Op(Offset.getImm()) == ARM_AM::add)
         Binary |= 1 << ARMII::U_BitShift;
-      // Immediate offset is multiplied by 4.
-      Binary |= ImmOffs >> 2;
+      Binary |= ImmOffs;
       emitWordLE(Binary);
       return;
     }
@@ -1233,15 +1324,7 @@ ARMCodeEmitter::emitVFPLoadStoreMultipleInstruction(const MachineInstr &MI) {
     Binary |= 0x1 << ARMII::W_BitShift;
 
   // First register is encoded in Dd.
-  unsigned RegD = MI.getOperand(4).getReg();
-  bool isSPVFP = false;
-  RegD = ARMRegisterInfo::getRegisterNumbering(RegD, isSPVFP);
-  if (!isSPVFP)
-    Binary |=   RegD               << ARMII::RegRdShift;
-  else {
-    Binary |= ((RegD & 0x1E) >> 1) << ARMII::RegRdShift;
-    Binary |=  (RegD & 0x01)       << ARMII::D_BitShift;
-  }
+  Binary |= encodeVFPRd(MI, 4);
 
   // Number of registers are encoded in offset field.
   unsigned NumRegs = 1;