static rtx maybe_mode_change (enum machine_mode orig_mode, enum machine_mode copy_mode, enum machine_mode new_mode, unsigned int regno, unsigned int copy_regno ATTRIBUTE_UNUSED) { if (GET_MODE_SIZE (copy_mode) < GET_MODE_SIZE (orig_mode) && GET_MODE_SIZE (copy_mode) < GET_MODE_SIZE (new_mode)) return NULL_RTX; if (orig_mode == new_mode) return gen_rtx_raw_REG (new_mode, regno); else if (mode_change_ok (orig_mode, new_mode, regno)) { int copy_nregs = hard_regno_nregs[copy_regno][copy_mode]; int use_nregs = hard_regno_nregs[copy_regno][new_mode]; int copy_offset = GET_MODE_SIZE (copy_mode) / copy_nregs * (copy_nregs - use_nregs); int offset = GET_MODE_SIZE (orig_mode) - GET_MODE_SIZE (new_mode) - copy_offset; int byteoffset = offset % UNITS_PER_WORD; int wordoffset = offset - byteoffset; offset = ((WORDS_BIG_ENDIAN ? wordoffset : 0) + (BYTES_BIG_ENDIAN ? byteoffset : 0)); regno += subreg_regno_offset (regno, orig_mode, offset, new_mode); if (HARD_REGNO_MODE_OK (regno, new_mode)) return gen_rtx_raw_REG (new_mode, regno); } return NULL_RTX; }
/// ValidateRegisterVariable - Check that a static "asm" variable is /// well-formed. If not, emit error messages and return true. If so, return /// false. bool ValidateRegisterVariable(tree decl) { const char *Name = IDENTIFIER_POINTER(DECL_ASSEMBLER_NAME(decl)); int RegNumber = decode_reg_name(Name); const Type *Ty = ConvertType(TREE_TYPE(decl)); // If this has already been processed, don't emit duplicate error messages. if (DECL_LLVM_SET_P(decl)) { // Error state encoded into DECL_LLVM. return cast<ConstantInt>(DECL_LLVM(decl))->getZExtValue(); } /* Detect errors in declaring global registers. */ if (RegNumber == -1) error("%Jregister name not specified for %qD", decl, decl); else if (RegNumber < 0) error("%Jinvalid register name for %qD", decl, decl); else if (TYPE_MODE(TREE_TYPE(decl)) == BLKmode) error("%Jdata type of %qD isn%'t suitable for a register", decl, decl); #if 0 // FIXME: enable this. else if (!HARD_REGNO_MODE_OK(RegNumber, TYPE_MODE(TREE_TYPE(decl)))) error("%Jregister specified for %qD isn%'t suitable for data type", decl, decl); #endif else if (DECL_INITIAL(decl) != 0 && TREE_STATIC(decl)) error("global register variable has initial value"); else if (!Ty->isFirstClassType()) sorry("%JLLVM cannot handle register variable %qD, report a bug", decl, decl); else { if (TREE_THIS_VOLATILE(decl)) warning("volatile register variables don%'t work as you might wish"); SET_DECL_LLVM(decl, ConstantInt::getFalse()); return false; // Everything ok. } SET_DECL_LLVM(decl, ConstantInt::getTrue()); return true; }