Homeowners insurance is a necessary expense of home ownership, but that doesn't mean you have to pay more than you need to for it. Fortunately, there are several ways you can save money on your homeowners insurance premium while still making sure you're covered against natural disasters and theft.
We consulted our home security experts, as well as a great guide from our friends at FLASH (Federal Alliance for Safe Homes) called "A Homeowners Insurance Guide to Natural Disasters," to bring you the most current information on how much coverage you really need. Whether you're in the market for a new policy, or you want to reduce the premium of your current one, here are six easy ways to keep more money in your pocket.
Tip 1: Shop around for the best value.
Shopping around is one of the best ways to reduce your homeowners insurance premium. Call at least three reputable homeowners insurance companies and compare policy coverages line for line, keeping in mind that the least expensive policy doesn't always offer the best value. According to "A Homeowners Insurance Guide to Natural Disasters," most property insurance policies exclude coverage for earthquakes and floods, so if these natural disasters are likely in your area, make sure to bargain accordingly.
The insurance business is notoriously competitive, so once you're armed with the details of each policy, don't hesitate to try and negotiate with your preferred provider for the lowest rate possible.
Tip 2: Protect your possessions with a monitored home security system.
Installing a monitored home security system is a money-saving tip many homeowners aren't aware of. In fact, a number of insurance companies may reward you with a discount of 15 percent or more if your home is protected by a monitored home security system. That's because homes with security systems are three times less likely to be burglarized than those without one, and that means there is less chance you'll file a claim. If you're considering protecting your home with a security system, don't hesitate to ask your insurance carrier how much you could save by doing so.
Tip 3: Raise your deductible.
Generally, the lower your insurance policy deductible (the amount you pay before your insurance takes over) the higher your insurance premium. Raising your policy deductible is a tried and true way of saving money on all types of insurance, including homeowners insurance. For example, raising your deductible from $500 to $1,000 could lower your premium by as much as 25 percent.
Tip 4: Make sure you don't have too much coverage.
There's a good chance your insurance agent warned you about the risks of being under-insured, but he may not have mentioned you can also be over-insured. Under-insured means you don't have enough insurance to adequately protect your belongings; over-insured means you're paying for more coverage than you need.
One of the best ways to prevent being over-insured and wasting your hard-earned money is to review your policy annually when it is up for renewal. Check the policy line for line, keeping an eye out for floaters, which is additional insurance for items that aren't covered in your standard policy, such as jewelry and artwork. If you no longer have the items, or their value has decreased substantially, you might be able to lower your coverage and save money.
Tip 5: Consolidate your insurance policies.
If you're looking to save money on your homeowners' insurance premium, consolidating various insurance policies could be the answer. Ask your insurance provider what other insurance products they sell, and how much you might save by buying more than one product, such as homeowners and auto. Not only is there a good chance you'll get a reduced rate on both policies, you'll also enjoy the convenience of paying just one bill.
Tip 6: Analyze your credit report.
Now you have one more reason to review your credit report for accuracy on an annual basis. Believing that a poor credit history correlates to an increased insurance risk, it's common for insurance companies to look at your credit report before quoting you a rate. The good news is, a superior credit history could reward you with lower than average premiums.
As you can see, there are many easy ways to reduce your homeowners' insurance premium without sacrificing coverage, and as we mentioned a home security system is one of the best. If you'd like to learn more about the many benefits of a home security system, click here.


text:
News Photos Archives Photos
Updated: Aug. 6, 2009 at 9:50 AM
Enola Gay Drops Bomb on Hiroshima(14 images)
The ground crew of the B-29 "Enola Gay" which atom-bombed Hiroshima, Japan. Col. Paul W. Tibbets, the pilot is the center. Photographed on Marianas Islands in Guam. The entire Enola Gay's flying crew on August 6, 1945 consisted of twelve men: Colonel Paul W. Tibbets, Jr. – aircraft commander, Captain Robert A. Lewis – co-pilot and Enola Gay's assigned aircraft commander, Major Thomas Ferebee – bombardier, Captain Theodore "Dutch" Van Kirk – navigator, U.S. Navy Captain William S. "Deak" Parsons – weaponeer and bomb commander, Lieutenant Jacob Beser – radar countermeasures (also the only man to fly on both nuclear bombing aircraft), Second Lieutenant Morris R. Jeppson – assistant weaponeer, Technical Sergeant George R. "Bob" Caron – tail gunner, Technical Sergeant Wyatt E. Duzenberry, flight engineer, Sergeant Joe S. Stiborik – radar, Sergeant Robert H. Shumard – assistant flight engineer, and Private First Class Richard M. Nelson – radio operator. (UPI Photo/USAF/Files)
License photo | Permalink
Paul Tibbets stands inf ront of the Enola Gay, the B29 bomber that delivered the atomic bomb to Hirioshima in Japan on August 6, 1945. (UPI Photo/USAF/Files)
"Little Boy" the atomic bomb that was dropped on Hiroshima August 6, 1945, is seen here in this undated handout photo. The bomb was released through the bomb bay doors of the "Enola Gay" from a height of about six miles. (UPI/File)
the Enolay Gay, the B29 bomber that dropped the atomic bomb on Hiroshima lies in pieces in the Smithsonian Institution's workshop, in Suitland, MD. Alongside the bomber is the fuselage of a World War II Heinkel 219 German night fighter. (UPI Photo/Files)
An unidentified newsman stands amid the rubble of Hiroshima in September 1945, a month after the atomic bomb was dropped on the city. The city had a population of roughly 400,000, three-quarters of them were civilians. (UPI/File)
A war correspondent examines the rubble left after the city of Hiroshima was leveled by the atomic bomb dropped at exactly 8:15AM on August 6, 1945. (UPI Photo/Files)
JAPAN: BOMBING, HIROSHIMA; ATOMIC BURST. At the time this photo was made, smoke billowed 20,000 feet above Hiroshima while smoke from the burst of the first atomic bomb had spread over 10,000 feet on the target at the base 0: the rising column. August 5, 1945. Two planes of the 509th Composite Group, part of the 313th Wing of the 20th Air Force, participated in this mission; one to carry the bomb, and the other to act as escort.(UPI Photo/USAF/Files)

redpajama_set_name: RedPajamaCommonCrawl


All of our products are governed by Terms and Conditions, which are made available to you on applicaiton.
Before using any of our products and services you should read the Conditions of Use for Central West Credit Union Account and Access Facility, which gives you information on the many ways in which you can access your account.
These Conditions of Use are made up of the Schedule of Fees, Charges and Transaction Limits, Summary of Accounts and Availability of Access Facilities and Accounts and Access Facility.
You should also read our Financial Services Guide, to assist you in deciding whether to use any of the financial services we offer.


I am excited to announce that Open Arms Counseling Center is officially open for business and accepting new clients. I will use this blog as a platform to share news about the practice, provide information on managing stress/health and wellness, and anything else related to serving the community.
I enjoy working in this field because it is very rewarding to help someone in need and observe their progress over time. At times, it honestly doesn't feel like work. I am very passionate about helping individuals heal emotionally and those who feel like they do not have a voice. I am also committed to assisting parents, teens, and individuals who want to make positive changes in their lives.
Please feel free to post comments. Thank you again.
Welcoming new people in our lives, community, organization and more, is a wonderful feeling to the people you welcome. It is also telling them that whatever, whoever you are or even wherever you came from, you appreciate them and accept them with all your heart. This is a great practice to start a relationship between people. Let us welcome each other and give them help when they needed it. Spread the love and peace in our life and also to the world.
Australian remote community school is providing best services. People can get best teaching experience from this school. They can get information about latest learning programs which are useful to enhance the knowledge of students. Teachers are adopting best methods for teaching.
for a healthy lifestyle, not a fad diet. that's how you lose weight and keep it. for good. For the exercise, don't overdo. s more managaeable that way. Walking, make you strengthen or build your muscle and.
Congratulations to you and with this newly opened counseling center. I am really happy for what you have achieved. I hope that sooner or later you will have more clients so that you will be a great counseling center. And who knows, you might have another branch so that you can help many more people. Also, I appreciate this line that you share " I enjoy working in this field because it is very rewarding to help someone in need and observe their progress over time." With that being said, I can sense your urge to help and the happiness that you have whenever you can help someone. Keep up the good work!
The physician then told him not to move - he was going to schedule surgery immediately. It seemed my husband had developed a subdural hematoma that covered his entire brain. I had several exalt lasers sitting in a pile, and simply equipping those made the mission much easier than trying to do it with the base weaponry.
Good blog post ! i enjoyed reading your post, lots of new ideas i have found. Thanks for sharing!
The information provided here was really helpful. Thanks for sharing this outstanding article. PhD dissertation writing services is helps your academic papers.
Get your hands on divine Gucci bags! Your new Gucci chain bag, tote, pouch, or Supreme Canvas shoulder bag is waiting for you.
Perfectly written post you have posted here, i hope in future you will share more informative post, nice shearing keep it up and keep shearing.
I will use this blog as a platform to share news about the practice.
Its really amazing and nice and valuable Article you have shared on your website. Keep sharing worthy info in future. Thanks for your interesting website.


These stories are about Sabrina and her sister, Daphne Grimm and are written by Michael Buckley. After their parents mysteriously disappeared, they are sent to live with their Grandma, Relda Grimm. That would have been fine – had not their parents told them they were the only family they ever had. Daphne seems to be having the time of her life and believes every thing their Granny Relda says. Naturally, Sabrina is suspicious, and who wouldn't be after living and running away – from dozens of foster parents? But, after a giant takes Granny Relda and her body guard, Mr. Canis (who is a part of the secret fairy tale community called the Everafters), Sabrina and Daphne rush to the rescue joined by Puck, a villain (or so he says), from A Midsummer Nights Dream and Jack (the Giant Killer). Together they go in search of Mr. Canis and Granny Relda and look for a secret Everafter community called The Scarlet Hand and meet all the fairytale characters they could ever hope to meet.
What I like about the series is how the author describes every thing. For instance, he gives a complete description of the characters, and he clearly describes the scenery and what is going on. I also like the plot a lot. He clearly describes what is happening, and I understood what was going on. It keeps me on the edge of my seat and wanting more, because every book ends in a cliff hanger. For instance, in the first book they don't find their parents, and it leaves you feeling like you have to read the next book. In the second book the author ends the book in the middle of a sentence.
What I didn't like is that he used a little "potty humor," and Sabrina fought a lot and called people names all the time – although they weren't necessarily bad words, they weren't kind names. Also, he uses jokes that aren't very funny.
I've read the whole series. Each book has action and adventure. The recommended age range for these books is 7-13 years old, but I recommend them for ages 11-adult or that a parent read the books first.
Hi Kenna, great review. I like how you described both what you liked and didn't like about the books, and how you gave advice to parents about reading them first. I'm sure they will appreciate that. Keep up the good work! C.
hey, for my lit class i read grimm's fairy tales and it was soo gory, my mom said she would not read any more! soooooooooooooooooo gory!
I believe you are thinking of a different book. My book review is about Sisters Grimm and not Grimm's Fairy Tales.


text:
using namespace llvm;

static
cl::opt<unsigned>
MaxNumOfUsesForConstExtenders("ga-max-num-uses-for-constant-extenders",
  cl::Hidden, cl::init(2),
  cl::desc("Maximum number of uses of a global address such that we still us a"
           "constant extended instruction"));

//===----------------------------------------------------------------------===//
// Instruction Selector Implementation
//===----------------------------------------------------------------------===//

namespace llvm {
  void initializeHexagonDAGToDAGISelPass(PassRegistry&);
}

//===--------------------------------------------------------------------===//
/// HexagonDAGToDAGISel - Hexagon specific code to select Hexagon machine
/// instructions for SelectionDAG operations.
///
namespace {
class HexagonDAGToDAGISel : public SelectionDAGISel {
  /// Subtarget - Keep a pointer to the Hexagon Subtarget around so that we can
  /// make the right decision when generating code for different targets.
  const HexagonSubtarget &Subtarget;

  // Keep a reference to HexagonTargetMachine.
  const HexagonTargetMachine& TM;
  const HexagonInstrInfo *TII;
  DenseMap<const GlobalValue *, unsigned> GlobalAddressUseCountMap;
public:
  explicit HexagonDAGToDAGISel(const HexagonTargetMachine &targetmachine,
                               CodeGenOpt::Level OptLevel)
    : SelectionDAGISel(targetmachine, OptLevel),
      Subtarget(targetmachine.getSubtarget<HexagonSubtarget>()),
      TM(targetmachine),
      TII(static_cast<const HexagonInstrInfo*>(TM.getInstrInfo())) {
    initializeHexagonDAGToDAGISelPass(*PassRegistry::getPassRegistry());
  }
  bool hasNumUsesBelowThresGA(SDNode *N) const;

  SDNode *Select(SDNode *N);

  // Complex Pattern Selectors.
  inline bool foldGlobalAddress(SDValue &N, SDValue &R);
  inline bool foldGlobalAddressGP(SDValue &N, SDValue &R);
  bool foldGlobalAddressImpl(SDValue &N, SDValue &R, bool ShouldLookForGP);
  bool SelectADDRri(SDValue& N, SDValue &R1, SDValue &R2);
  bool SelectADDRriS11_0(SDValue& N, SDValue &R1, SDValue &R2);
  bool SelectADDRriS11_1(SDValue& N, SDValue &R1, SDValue &R2);
  bool SelectADDRriS11_2(SDValue& N, SDValue &R1, SDValue &R2);
  bool SelectMEMriS11_2(SDValue& Addr, SDValue &Base, SDValue &Offset);
  bool SelectADDRriS11_3(SDValue& N, SDValue &R1, SDValue &R2);
  bool SelectADDRrr(SDValue &Addr, SDValue &Base, SDValue &Offset);
  bool SelectADDRriU6_0(SDValue& N, SDValue &R1, SDValue &R2);
  bool SelectADDRriU6_1(SDValue& N, SDValue &R1, SDValue &R2);
  bool SelectADDRriU6_2(SDValue& N, SDValue &R1, SDValue &R2);

  virtual const char *getPassName() const {
    return "Hexagon DAG->DAG Pattern Instruction Selection";
  }

  /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
  /// inline asm expressions.
  virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op,
                                            char ConstraintCode,
                                            std::vector<SDValue> &OutOps);
  bool SelectAddr(SDNode *Op, SDValue Addr, SDValue &Base, SDValue &Offset);

  SDNode *SelectLoad(SDNode *N);
  SDNode *SelectBaseOffsetLoad(LoadSDNode *LD, DebugLoc dl);
  SDNode *SelectIndexedLoad(LoadSDNode *LD, DebugLoc dl);
  SDNode *SelectIndexedLoadZeroExtend64(LoadSDNode *LD, unsigned Opcode,
                                        DebugLoc dl);
  SDNode *SelectIndexedLoadSignExtend64(LoadSDNode *LD, unsigned Opcode,
                                        DebugLoc dl);
  SDNode *SelectBaseOffsetStore(StoreSDNode *ST, DebugLoc dl);
  SDNode *SelectIndexedStore(StoreSDNode *ST, DebugLoc dl);
  SDNode *SelectStore(SDNode *N);
  SDNode *SelectSHL(SDNode *N);
  SDNode *SelectSelect(SDNode *N);
  SDNode *SelectTruncate(SDNode *N);
  SDNode *SelectMul(SDNode *N);
  SDNode *SelectZeroExtend(SDNode *N);
  SDNode *SelectIntrinsicWOChain(SDNode *N);
  SDNode *SelectIntrinsicWChain(SDNode *N);
  SDNode *SelectConstant(SDNode *N);
  SDNode *SelectConstantFP(SDNode *N);
  SDNode *SelectAdd(SDNode *N);
  bool isConstExtProfitable(SDNode *N) const;

// XformMskToBitPosU5Imm - Returns the bit position which
// the single bit 32 bit mask represents.
// Used in Clr and Set bit immediate memops.
SDValue XformMskToBitPosU5Imm(uint32_t Imm) {
  int32_t bitPos;
  bitPos = Log2_32(Imm);
  assert(bitPos >= 0 && bitPos < 32 &&
         "Constant out of range for 32 BitPos Memops");
  return CurDAG->getTargetConstant(bitPos, MVT::i32);
}

// XformMskToBitPosU4Imm - Returns the bit position which the single bit 16 bit
// mask represents. Used in Clr and Set bit immediate memops.
SDValue XformMskToBitPosU4Imm(uint16_t Imm) {
  return XformMskToBitPosU5Imm(Imm);
}

// XformMskToBitPosU3Imm - Returns the bit position which the single bit 8 bit
// mask represents. Used in Clr and Set bit immediate memops.
SDValue XformMskToBitPosU3Imm(uint8_t Imm) {
  return XformMskToBitPosU5Imm(Imm);
}

// Return true if there is exactly one bit set in V, i.e., if V is one of the
// following integers: 2^0, 2^1, ..., 2^31.
bool ImmIsSingleBit(uint32_t v) const {
  uint32_t c = CountPopulation_64(v);
  // Only return true if we counted 1 bit.
  return c == 1;
}

// XformM5ToU5Imm - Return a target constant with the specified value, of type
// i32 where the negative literal is transformed into a positive literal for
// use in -= memops.
inline SDValue XformM5ToU5Imm(signed Imm) {
   assert( (Imm >= -31 && Imm <= -1)  && "Constant out of range for Memops");
   return CurDAG->getTargetConstant( - Imm, MVT::i32);
}

// XformU7ToU7M1Imm - Return a target constant decremented by 1, in range
// [1..128], used in cmpb.gtu instructions.
inline SDValue XformU7ToU7M1Imm(signed Imm) {
  assert((Imm >= 1 && Imm <= 128) && "Constant out of range for cmpb op");
  return CurDAG->getTargetConstant(Imm - 1, MVT::i8);
}

// XformS8ToS8M1Imm - Return a target constant decremented by 1.
inline SDValue XformSToSM1Imm(signed Imm) {
  return CurDAG->getTargetConstant(Imm - 1, MVT::i32);
}

// XformU8ToU8M1Imm - Return a target constant decremented by 1.
inline SDValue XformUToUM1Imm(unsigned Imm) {
  assert((Imm >= 1) && "Cannot decrement unsigned int less than 1");
  return CurDAG->getTargetConstant(Imm - 1, MVT::i32);
}

// Include the pieces autogenerated from the target description.
#include "HexagonGenDAGISel.inc"
};
}  // end anonymous namespace

/// createHexagonISelDag - This pass converts a legalized DAG into a
/// Hexagon-specific DAG, ready for instruction scheduling.
///
FunctionPass *llvm::createHexagonISelDag(const HexagonTargetMachine &TM,
                                         CodeGenOpt::Level OptLevel) {
  return new HexagonDAGToDAGISel(TM, OptLevel);
}

static void initializePassOnce(PassRegistry &Registry) {
  const char *Name = "Hexagon DAG->DAG Pattern Instruction Selection";
  PassInfo *PI = new PassInfo(Name, "hexagon-isel",
                              &SelectionDAGISel::ID, 0, false, false);
  Registry.registerPass(*PI, true);
}

void llvm::initializeHexagonDAGToDAGISelPass(PassRegistry &Registry) {
  CALL_ONCE_INITIALIZATION(initializePassOnce)
}

static bool IsS11_0_Offset(SDNode * S) {
    ConstantSDNode *N = cast<ConstantSDNode>(S);

  // immS16 predicate - True if the immediate fits in a 16-bit sign extended
  // field.
  int64_t v = (int64_t)N->getSExtValue();
  return isInt<11>(v);
}

static bool IsS11_1_Offset(SDNode * S) {
    ConstantSDNode *N = cast<ConstantSDNode>(S);

  // immS16 predicate - True if the immediate fits in a 16-bit sign extended
  // field.
  int64_t v = (int64_t)N->getSExtValue();
  return isShiftedInt<11,1>(v);
}

static bool IsS11_2_Offset(SDNode * S) {
    ConstantSDNode *N = cast<ConstantSDNode>(S);

  // immS16 predicate - True if the immediate fits in a 16-bit sign extended
  // field.
  int64_t v = (int64_t)N->getSExtValue();
  return isShiftedInt<11,2>(v);
}

static bool IsS11_3_Offset(SDNode * S) {
    ConstantSDNode *N = cast<ConstantSDNode>(S);

  // immS16 predicate - True if the immediate fits in a 16-bit sign extended
  // field.
  int64_t v = (int64_t)N->getSExtValue();
  return isShiftedInt<11,3>(v);
}

static bool IsU6_0_Offset(SDNode * S) {
    ConstantSDNode *N = cast<ConstantSDNode>(S);

  // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
  // field.
  int64_t v = (int64_t)N->getSExtValue();
  return isUInt<6>(v);
}

static bool IsU6_1_Offset(SDNode * S) {
    ConstantSDNode *N = cast<ConstantSDNode>(S);

  // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
  // field.
  int64_t v = (int64_t)N->getSExtValue();
  return isShiftedUInt<6,1>(v);
}

static bool IsU6_2_Offset(SDNode * S) {
    ConstantSDNode *N = cast<ConstantSDNode>(S);

  // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
  // field.
  int64_t v = (int64_t)N->getSExtValue();
  return isShiftedUInt<6,2>(v);
}

// Intrinsics that return a a predicate.
static unsigned doesIntrinsicReturnPredicate(unsigned ID)
{
  switch (ID) {
    default:
      return 0;
    case Intrinsic::hexagon_C2_cmpeq:
    case Intrinsic::hexagon_C2_cmpgt:
    case Intrinsic::hexagon_C2_cmpgtu:
    case Intrinsic::hexagon_C2_cmpgtup:
    case Intrinsic::hexagon_C2_cmpgtp:
    case Intrinsic::hexagon_C2_cmpeqp:
    case Intrinsic::hexagon_C2_bitsset:
    case Intrinsic::hexagon_C2_bitsclr:
    case Intrinsic::hexagon_C2_cmpeqi:
    case Intrinsic::hexagon_C2_cmpgti:
    case Intrinsic::hexagon_C2_cmpgtui:
    case Intrinsic::hexagon_C2_cmpgei:
    case Intrinsic::hexagon_C2_cmpgeui:
    case Intrinsic::hexagon_C2_cmplt:
    case Intrinsic::hexagon_C2_cmpltu:
    case Intrinsic::hexagon_C2_bitsclri:
    case Intrinsic::hexagon_C2_and:
    case Intrinsic::hexagon_C2_or:
    case Intrinsic::hexagon_C2_xor:
    case Intrinsic::hexagon_C2_andn:
    case Intrinsic::hexagon_C2_not:
    case Intrinsic::hexagon_C2_orn:
    case Intrinsic::hexagon_C2_pxfer_map:
    case Intrinsic::hexagon_C2_any8:
    case Intrinsic::hexagon_C2_all8:
    case Intrinsic::hexagon_A2_vcmpbeq:
    case Intrinsic::hexagon_A2_vcmpbgtu:
    case Intrinsic::hexagon_A2_vcmpheq:
    case Intrinsic::hexagon_A2_vcmphgt:
    case Intrinsic::hexagon_A2_vcmphgtu:
    case Intrinsic::hexagon_A2_vcmpweq:
    case Intrinsic::hexagon_A2_vcmpwgt:
    case Intrinsic::hexagon_A2_vcmpwgtu:
    case Intrinsic::hexagon_C2_tfrrp:
    case Intrinsic::hexagon_S2_tstbit_i:
    case Intrinsic::hexagon_S2_tstbit_r:
      return 1;
  }
}

// Intrinsics that have predicate operands.
static unsigned doesIntrinsicContainPredicate(unsigned ID)
{
  switch (ID) {
    default:
      return 0;
    case Intrinsic::hexagon_C2_tfrpr:
      return Hexagon::TFR_RsPd;
    case Intrinsic::hexagon_C2_and:
      return Hexagon::AND_pp;
    case Intrinsic::hexagon_C2_xor:
      return Hexagon::XOR_pp;
    case Intrinsic::hexagon_C2_or:
      return Hexagon::OR_pp;
    case Intrinsic::hexagon_C2_not:
      return Hexagon::NOT_p;
    case Intrinsic::hexagon_C2_any8:
      return Hexagon::ANY_pp;
    case Intrinsic::hexagon_C2_all8:
      return Hexagon::ALL_pp;
    case Intrinsic::hexagon_C2_vitpack:
      return Hexagon::VITPACK_pp;
    case Intrinsic::hexagon_C2_mask:
      return Hexagon::MASK_p;
    case Intrinsic::hexagon_C2_mux:
      return Hexagon::MUX_rr;

      // Mapping hexagon_C2_muxir to MUX_pri.  This is pretty weird - but
      // that's how it's mapped in q6protos.h.
    case Intrinsic::hexagon_C2_muxir:
      return Hexagon::MUX_ri;

      // Mapping hexagon_C2_muxri to MUX_pir.  This is pretty weird - but
      // that's how it's mapped in q6protos.h.
    case Intrinsic::hexagon_C2_muxri:
      return Hexagon::MUX_ir;

    case Intrinsic::hexagon_C2_muxii:
      return Hexagon::MUX_ii;
    case Intrinsic::hexagon_C2_vmux:
      return Hexagon::VMUX_prr64;
    case Intrinsic::hexagon_S2_valignrb:
      return Hexagon::VALIGN_rrp;
    case Intrinsic::hexagon_S2_vsplicerb:
      return Hexagon::VSPLICE_rrp;
  }
}

static bool OffsetFitsS11(EVT MemType, int64_t Offset) {
  if (MemType == MVT::i64 && isShiftedInt<11,3>(Offset)) {
    return true;
  }
  if (MemType == MVT::i32 && isShiftedInt<11,2>(Offset)) {
    return true;
  }
  if (MemType == MVT::i16 && isShiftedInt<11,1>(Offset)) {
    return true;
  }
  if (MemType == MVT::i8 && isInt<11>(Offset)) {
    return true;
  }
  return false;
}

//
// Try to lower loads of GlobalAdresses into base+offset loads.  Custom
// lowering for GlobalAddress nodes has already turned it into a
// CONST32.
//
SDNode *HexagonDAGToDAGISel::SelectBaseOffsetLoad(LoadSDNode *LD, DebugLoc dl) {
  SDValue Chain = LD->getChain();
  SDNode* Const32 = LD->getBasePtr().getNode();
  unsigned Opcode = 0;

  if (Const32->getOpcode() == HexagonISD::CONST32 &&
      ISD::isNormalLoad(LD)) {
    SDValue Base = Const32->getOperand(0);
    EVT LoadedVT = LD->getMemoryVT();
    int64_t Offset = cast<GlobalAddressSDNode>(Base)->getOffset();
    if (Offset != 0 && OffsetFitsS11(LoadedVT, Offset)) {
      MVT PointerTy = TLI.getPointerTy();
      const GlobalValue* GV =
        cast<GlobalAddressSDNode>(Base)->getGlobal();
      SDValue TargAddr =
        CurDAG->getTargetGlobalAddress(GV, dl, PointerTy, 0);
      SDNode* NewBase = CurDAG->getMachineNode(Hexagon::CONST32_set,
                                               dl, PointerTy,
                                               TargAddr);
      // Figure out base + offset opcode
      if (LoadedVT == MVT::i64) Opcode = Hexagon::LDrid_indexed;
      else if (LoadedVT == MVT::i32) Opcode = Hexagon::LDriw_indexed;
      else if (LoadedVT == MVT::i16) Opcode = Hexagon::LDrih_indexed;
      else if (LoadedVT == MVT::i8) Opcode = Hexagon::LDrib_indexed;
      else llvm_unreachable("unknown memory type");

      // Build indexed load.
      SDValue TargetConstOff = CurDAG->getTargetConstant(Offset, PointerTy);
      SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
                                              LD->getValueType(0),
                                              MVT::Other,
                                              SDValue(NewBase,0),
                                              TargetConstOff,
                                              Chain);
      MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
      MemOp[0] = LD->getMemOperand();
      cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
      ReplaceUses(LD, Result);
      return Result;
    }
  }

  return SelectCode(LD);
}

SDNode *HexagonDAGToDAGISel::SelectIndexedLoadSignExtend64(LoadSDNode *LD,
                                                           unsigned Opcode,
                                                           DebugLoc dl)
{
  SDValue Chain = LD->getChain();
  EVT LoadedVT = LD->getMemoryVT();
  SDValue Base = LD->getBasePtr();
  SDValue Offset = LD->getOffset();
  SDNode *OffsetNode = Offset.getNode();
  int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
  SDValue N1 = LD->getOperand(1);
  SDValue CPTmpN1_0;
  SDValue CPTmpN1_1;
  if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) &&
      N1.getNode()->getValueType(0) == MVT::i32) {
    if (TII->isValidAutoIncImm(LoadedVT, Val)) {
      SDValue TargetConst = CurDAG->getTargetConstant(Val, MVT::i32);
      SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32, MVT::i32,
                                                MVT::Other, Base, TargetConst,
                                                Chain);
      SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::SXTW, dl, MVT::i64,
                                                SDValue(Result_1, 0));
      MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
      MemOp[0] = LD->getMemOperand();
      cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
      const SDValue Froms[] = { SDValue(LD, 0),
                                SDValue(LD, 1),
                                SDValue(LD, 2)
      };
      const SDValue Tos[]   = { SDValue(Result_2, 0),
                                SDValue(Result_1, 1),
                                SDValue(Result_1, 2)
      };
      ReplaceUses(Froms, Tos, 3);
      return Result_2;
    }
    SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
    SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
    SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
                                              MVT::Other, Base, TargetConst0,
                                              Chain);
    SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::SXTW, dl,
                                                MVT::i64, SDValue(Result_1, 0));
    SDNode* Result_3 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl,
                                              MVT::i32, Base, TargetConstVal,
                                                SDValue(Result_1, 1));
    MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
    MemOp[0] = LD->getMemOperand();
    cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
    const SDValue Froms[] = { SDValue(LD, 0),
                              SDValue(LD, 1),
                              SDValue(LD, 2)
    };
    const SDValue Tos[]   = { SDValue(Result_2, 0),
                              SDValue(Result_3, 0),
                              SDValue(Result_1, 1)
    };
    ReplaceUses(Froms, Tos, 3);
    return Result_2;
  }
  return SelectCode(LD);
}

SDNode *HexagonDAGToDAGISel::SelectIndexedLoadZeroExtend64(LoadSDNode *LD,
                                                           unsigned Opcode,
                                                           DebugLoc dl)
{
  SDValue Chain = LD->getChain();
  EVT LoadedVT = LD->getMemoryVT();
  SDValue Base = LD->getBasePtr();
  SDValue Offset = LD->getOffset();
  SDNode *OffsetNode = Offset.getNode();
  int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
  SDValue N1 = LD->getOperand(1);
  SDValue CPTmpN1_0;
  SDValue CPTmpN1_1;
  if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) &&
      N1.getNode()->getValueType(0) == MVT::i32) {
    if (TII->isValidAutoIncImm(LoadedVT, Val)) {
      SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
      SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
      SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
                                                MVT::i32, MVT::Other, Base,
                                                TargetConstVal, Chain);
      SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32,
                                                TargetConst0);
      SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl,
                                                MVT::i64, MVT::Other,
                                                SDValue(Result_2,0),
                                                SDValue(Result_1,0));
      MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
      MemOp[0] = LD->getMemOperand();
      cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
      const SDValue Froms[] = { SDValue(LD, 0),
                                SDValue(LD, 1),
                                SDValue(LD, 2)
      };
      const SDValue Tos[]   = { SDValue(Result_3, 0),
                                SDValue(Result_1, 1),
                                SDValue(Result_1, 2)
      };
      ReplaceUses(Froms, Tos, 3);
      return Result_3;
    }

    // Generate an indirect load.
    SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
    SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
    SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
                                              MVT::Other,
                                              Base, TargetConst0, Chain);
    SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32,
                                              TargetConst0);
    SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl,
                                              MVT::i64, MVT::Other,
                                              SDValue(Result_2,0),
                                              SDValue(Result_1,0));
    // Add offset to base.
    SDNode* Result_4 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32,
                                              Base, TargetConstVal,
                                              SDValue(Result_1, 1));
    MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
    MemOp[0] = LD->getMemOperand();
    cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
    const SDValue Froms[] = { SDValue(LD, 0),
                              SDValue(LD, 1),
                              SDValue(LD, 2)
    };
    const SDValue Tos[]   = { SDValue(Result_3, 0), // Load value.
                              SDValue(Result_4, 0), // New address.
                              SDValue(Result_1, 1)
    };
    ReplaceUses(Froms, Tos, 3);
    return Result_3;
  }

  return SelectCode(LD);
}

SDNode *HexagonDAGToDAGISel::SelectIndexedLoad(LoadSDNode *LD, DebugLoc dl) {
  SDValue Chain = LD->getChain();
  SDValue Base = LD->getBasePtr();
  SDValue Offset = LD->getOffset();
  SDNode *OffsetNode = Offset.getNode();
  // Get the constant value.
  int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
  EVT LoadedVT = LD->getMemoryVT();
  unsigned Opcode = 0;

  // Check for zero ext loads.
  bool zextval = (LD->getExtensionType() == ISD::ZEXTLOAD);

  // Figure out the opcode.
  if (LoadedVT == MVT::i64) {
    if (TII->isValidAutoIncImm(LoadedVT, Val))
      Opcode = Hexagon::POST_LDrid;
    else
      Opcode = Hexagon::LDrid;
  } else if (LoadedVT == MVT::i32) {
    if (TII->isValidAutoIncImm(LoadedVT, Val))
      Opcode = Hexagon::POST_LDriw;
    else
      Opcode = Hexagon::LDriw;
  } else if (LoadedVT == MVT::i16) {
    if (TII->isValidAutoIncImm(LoadedVT, Val))
      Opcode = zextval ? Hexagon::POST_LDriuh : Hexagon::POST_LDrih;
    else
      Opcode = zextval ? Hexagon::LDriuh : Hexagon::LDrih;
  } else if (LoadedVT == MVT::i8) {
    if (TII->isValidAutoIncImm(LoadedVT, Val))
      Opcode = zextval ? Hexagon::POST_LDriub : Hexagon::POST_LDrib;
    else
      Opcode = zextval ? Hexagon::LDriub : Hexagon::LDrib;
  } else
    llvm_unreachable("unknown memory type");

  // For zero ext i64 loads, we need to add combine instructions.
  if (LD->getValueType(0) == MVT::i64 &&
      LD->getExtensionType() == ISD::ZEXTLOAD) {
    return SelectIndexedLoadZeroExtend64(LD, Opcode, dl);
  }
  if (LD->getValueType(0) == MVT::i64 &&
             LD->getExtensionType() == ISD::SEXTLOAD) {
    // Handle sign ext i64 loads.
    return SelectIndexedLoadSignExtend64(LD, Opcode, dl);
  }
  if (TII->isValidAutoIncImm(LoadedVT, Val)) {
    SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
    SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
                                            LD->getValueType(0),
                                            MVT::i32, MVT::Other, Base,
                                            TargetConstVal, Chain);
    MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
    MemOp[0] = LD->getMemOperand();
    cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
    const SDValue Froms[] = { SDValue(LD, 0),
                              SDValue(LD, 1),
                              SDValue(LD, 2)
    };
    const SDValue Tos[]   = { SDValue(Result, 0),
                              SDValue(Result, 1),
                              SDValue(Result, 2)
    };
    ReplaceUses(Froms, Tos, 3);
    return Result;
  } else {
    SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
    SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
    SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl,
                                              LD->getValueType(0),
                                              MVT::Other, Base, TargetConst0,
                                              Chain);
    SDNode* Result_2 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32,
                                              Base, TargetConstVal,
                                              SDValue(Result_1, 1));
    MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
    MemOp[0] = LD->getMemOperand();
    cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
    const SDValue Froms[] = { SDValue(LD, 0),
                              SDValue(LD, 1),
                              SDValue(LD, 2)
    };
    const SDValue Tos[]   = { SDValue(Result_1, 0),
                              SDValue(Result_2, 0),
                              SDValue(Result_1, 1)
    };
    ReplaceUses(Froms, Tos, 3);
    return Result_1;
  }
}

SDNode *HexagonDAGToDAGISel::SelectLoad(SDNode *N) {
  SDNode *result;
  DebugLoc dl = N->getDebugLoc();
  LoadSDNode *LD = cast<LoadSDNode>(N);
  ISD::MemIndexedMode AM = LD->getAddressingMode();

  // Handle indexed loads.
  if (AM != ISD::UNINDEXED) {
    result = SelectIndexedLoad(LD, dl);
  } else {
    result = SelectBaseOffsetLoad(LD, dl);
  }

  return result;
}

SDNode *HexagonDAGToDAGISel::SelectIndexedStore(StoreSDNode *ST, DebugLoc dl) {
  SDValue Chain = ST->getChain();
  SDValue Base = ST->getBasePtr();
  SDValue Offset = ST->getOffset();
  SDValue Value = ST->getValue();
  SDNode *OffsetNode = Offset.getNode();
  // Get the constant value.
  int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
  EVT StoredVT = ST->getMemoryVT();

  // Offset value must be within representable range
  // and must have correct alignment properties.
  if (TII->isValidAutoIncImm(StoredVT, Val)) {
    SDValue Ops[] = {Base, CurDAG->getTargetConstant(Val, MVT::i32), Value,
                     Chain};
    unsigned Opcode = 0;

    // Figure out the post inc version of opcode.
    if (StoredVT == MVT::i64) Opcode = Hexagon::POST_STdri;
    else if (StoredVT == MVT::i32) Opcode = Hexagon::POST_STwri;
    else if (StoredVT == MVT::i16) Opcode = Hexagon::POST_SThri;
    else if (StoredVT == MVT::i8) Opcode = Hexagon::POST_STbri;
    else llvm_unreachable("unknown memory type");

    // Build post increment store.
    SDNode* Result = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
                                            MVT::Other, Ops);
    MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
    MemOp[0] = ST->getMemOperand();
    cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);

    ReplaceUses(ST, Result);
    ReplaceUses(SDValue(ST,1), SDValue(Result,1));
    return Result;
  }

  // Note: Order of operands matches the def of instruction:
  // def STrid : STInst<(outs), (ins MEMri:$addr, DoubleRegs:$src1), ...
  // and it differs for POST_ST* for instance.
  SDValue Ops[] = { Base, CurDAG->getTargetConstant(0, MVT::i32), Value,
                    Chain};
  unsigned Opcode = 0;

  // Figure out the opcode.
  if (StoredVT == MVT::i64) Opcode = Hexagon::STrid;
  else if (StoredVT == MVT::i32) Opcode = Hexagon::STriw_indexed;
  else if (StoredVT == MVT::i16) Opcode = Hexagon::STrih;
  else if (StoredVT == MVT::i8) Opcode = Hexagon::STrib;
  else llvm_unreachable("unknown memory type");

  // Build regular store.
  SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
  SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
  // Build splitted incriment instruction.
  SDNode* Result_2 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32,
                                            Base,
                                            TargetConstVal,
                                            SDValue(Result_1, 0));
  MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
  MemOp[0] = ST->getMemOperand();
  cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);

  ReplaceUses(SDValue(ST,0), SDValue(Result_2,0));
  ReplaceUses(SDValue(ST,1), SDValue(Result_1,0));
  return Result_2;
}

SDNode *HexagonDAGToDAGISel::SelectBaseOffsetStore(StoreSDNode *ST,
                                                   DebugLoc dl) {
  SDValue Chain = ST->getChain();
  SDNode* Const32 = ST->getBasePtr().getNode();
  SDValue Value = ST->getValue();
  unsigned Opcode = 0;

  // Try to lower stores of GlobalAdresses into indexed stores.  Custom
  // lowering for GlobalAddress nodes has already turned it into a
  // CONST32.  Avoid truncating stores for the moment.  Post-inc stores
  // do the same.  Don't think there's a reason for it, so will file a
  // bug to fix.
  if ((Const32->getOpcode() == HexagonISD::CONST32) &&
      !(Value.getValueType() == MVT::i64 && ST->isTruncatingStore())) {
    SDValue Base = Const32->getOperand(0);
    if (Base.getOpcode() == ISD::TargetGlobalAddress) {
      EVT StoredVT = ST->getMemoryVT();
      int64_t Offset = cast<GlobalAddressSDNode>(Base)->getOffset();
      if (Offset != 0 && OffsetFitsS11(StoredVT, Offset)) {
        MVT PointerTy = TLI.getPointerTy();
        const GlobalValue* GV =
          cast<GlobalAddressSDNode>(Base)->getGlobal();
        SDValue TargAddr =
          CurDAG->getTargetGlobalAddress(GV, dl, PointerTy, 0);
        SDNode* NewBase = CurDAG->getMachineNode(Hexagon::CONST32_set,
                                                 dl, PointerTy,
                                                 TargAddr);

        // Figure out base + offset opcode
        if (StoredVT == MVT::i64) Opcode = Hexagon::STrid_indexed;
        else if (StoredVT == MVT::i32) Opcode = Hexagon::STriw_indexed;
        else if (StoredVT == MVT::i16) Opcode = Hexagon::STrih_indexed;
        else if (StoredVT == MVT::i8) Opcode = Hexagon::STrib_indexed;
        else llvm_unreachable("unknown memory type");

        SDValue Ops[] = {SDValue(NewBase,0),
                         CurDAG->getTargetConstant(Offset,PointerTy),
                         Value, Chain};
        // build indexed store
        SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
                                                MVT::Other, Ops);
        MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
        MemOp[0] = ST->getMemOperand();
        cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
        ReplaceUses(ST, Result);
        return Result;
      }
    }
  }

  return SelectCode(ST);
}

SDNode *HexagonDAGToDAGISel::SelectStore(SDNode *N) {
  DebugLoc dl = N->getDebugLoc();
  StoreSDNode *ST = cast<StoreSDNode>(N);
  ISD::MemIndexedMode AM = ST->getAddressingMode();

  // Handle indexed stores.
  if (AM != ISD::UNINDEXED) {
    return SelectIndexedStore(ST, dl);
  }

  return SelectBaseOffsetStore(ST, dl);
}

SDNode *HexagonDAGToDAGISel::SelectMul(SDNode *N) {
  DebugLoc dl = N->getDebugLoc();

  //
  // %conv.i = sext i32 %tmp1 to i64
  // %conv2.i = sext i32 %add to i64
  // %mul.i = mul nsw i64 %conv2.i, %conv.i
  //
  //   --- match with the following ---
  //
  // %mul.i = mpy (%tmp1, %add)
  //

  if (N->getValueType(0) == MVT::i64) {
    // Shifting a i64 signed multiply.
    SDValue MulOp0 = N->getOperand(0);
    SDValue MulOp1 = N->getOperand(1);

    SDValue OP0;
    SDValue OP1;

    // Handle sign_extend and sextload.
    if (MulOp0.getOpcode() == ISD::SIGN_EXTEND) {
      SDValue Sext0 = MulOp0.getOperand(0);
      if (Sext0.getNode()->getValueType(0) != MVT::i32) {
        return SelectCode(N);
      }

      OP0 = Sext0;
    } else if (MulOp0.getOpcode() == ISD::LOAD) {
      LoadSDNode *LD = cast<LoadSDNode>(MulOp0.getNode());
      if (LD->getMemoryVT() != MVT::i32 ||
          LD->getExtensionType() != ISD::SEXTLOAD ||
          LD->getAddressingMode() != ISD::UNINDEXED) {
        return SelectCode(N);
      }

      SDValue Chain = LD->getChain();
      SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
      OP0 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
                                            MVT::Other,
                                            LD->getBasePtr(), TargetConst0,
                                            Chain), 0);
    } else {
      return SelectCode(N);
    }

    // Same goes for the second operand.
    if (MulOp1.getOpcode() == ISD::SIGN_EXTEND) {
      SDValue Sext1 = MulOp1.getOperand(0);
      if (Sext1.getNode()->getValueType(0) != MVT::i32) {
        return SelectCode(N);
      }

      OP1 = Sext1;
    } else if (MulOp1.getOpcode() == ISD::LOAD) {
      LoadSDNode *LD = cast<LoadSDNode>(MulOp1.getNode());
      if (LD->getMemoryVT() != MVT::i32 ||
          LD->getExtensionType() != ISD::SEXTLOAD ||
          LD->getAddressingMode() != ISD::UNINDEXED) {
        return SelectCode(N);
      }

      SDValue Chain = LD->getChain();
      SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
      OP1 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
                                            MVT::Other,
                                            LD->getBasePtr(), TargetConst0,
                                            Chain), 0);
    } else {
      return SelectCode(N);
    }

    // Generate a mpy instruction.
    SDNode *Result = CurDAG->getMachineNode(Hexagon::MPY64, dl, MVT::i64,
                                            OP0, OP1);
    ReplaceUses(N, Result);
    return Result;
  }

  return SelectCode(N);
}

SDNode *HexagonDAGToDAGISel::SelectSelect(SDNode *N) {
  DebugLoc dl = N->getDebugLoc();
  SDValue N0 = N->getOperand(0);
  if (N0.getOpcode() == ISD::SETCC) {
    SDValue N00 = N0.getOperand(0);
    if (N00.getOpcode() == ISD::SIGN_EXTEND_INREG) {
      SDValue N000 = N00.getOperand(0);
      SDValue N001 = N00.getOperand(1);
      if (cast<VTSDNode>(N001)->getVT() == MVT::i16) {
        SDValue N01 = N0.getOperand(1);
        SDValue N02 = N0.getOperand(2);

        // Pattern: (select:i32 (setcc:i1 (sext_inreg:i32 IntRegs:i32:$src2,
        // i16:Other),IntRegs:i32:$src1, SETLT:Other),IntRegs:i32:$src1,
        // IntRegs:i32:$src2)
        // Emits: (MAXh_rr:i32 IntRegs:i32:$src1, IntRegs:i32:$src2)
        // Pattern complexity = 9  cost = 1  size = 0.
        if (cast<CondCodeSDNode>(N02)->get() == ISD::SETLT) {
          SDValue N1 = N->getOperand(1);
          if (N01 == N1) {
            SDValue N2 = N->getOperand(2);
            if (N000 == N2 &&
                N0.getNode()->getValueType(N0.getResNo()) == MVT::i1 &&
                N00.getNode()->getValueType(N00.getResNo()) == MVT::i32) {
              SDNode *SextNode = CurDAG->getMachineNode(Hexagon::SXTH, dl,
                                                        MVT::i32, N000);
              SDNode *Result = CurDAG->getMachineNode(Hexagon::MAXw_rr, dl,
                                                      MVT::i32,
                                                      SDValue(SextNode, 0),
                                                      N1);
              ReplaceUses(N, Result);
              return Result;
            }
          }
        }

        // Pattern: (select:i32 (setcc:i1 (sext_inreg:i32 IntRegs:i32:$src2,
        // i16:Other), IntRegs:i32:$src1, SETGT:Other), IntRegs:i32:$src1,
        // IntRegs:i32:$src2)
        // Emits: (MINh_rr:i32 IntRegs:i32:$src1, IntRegs:i32:$src2)
        // Pattern complexity = 9  cost = 1  size = 0.
        if (cast<CondCodeSDNode>(N02)->get() == ISD::SETGT) {
          SDValue N1 = N->getOperand(1);
          if (N01 == N1) {
            SDValue N2 = N->getOperand(2);
            if (N000 == N2 &&
                N0.getNode()->getValueType(N0.getResNo()) == MVT::i1 &&
                N00.getNode()->getValueType(N00.getResNo()) == MVT::i32) {
              SDNode *SextNode = CurDAG->getMachineNode(Hexagon::SXTH, dl,
                                                        MVT::i32, N000);
              SDNode *Result = CurDAG->getMachineNode(Hexagon::MINw_rr, dl,
                                                      MVT::i32,
                                                      SDValue(SextNode, 0),
                                                      N1);
              ReplaceUses(N, Result);
              return Result;
            }
          }
        }
      }
    }
  }

  return SelectCode(N);
}

SDNode *HexagonDAGToDAGISel::SelectTruncate(SDNode *N) {
  DebugLoc dl = N->getDebugLoc();
  SDValue Shift = N->getOperand(0);

  //
  // %conv.i = sext i32 %tmp1 to i64
  // %conv2.i = sext i32 %add to i64
  // %mul.i = mul nsw i64 %conv2.i, %conv.i
  // %shr5.i = lshr i64 %mul.i, 32
  // %conv3.i = trunc i64 %shr5.i to i32
  //
  //   --- match with the following ---
  //
  // %conv3.i = mpy (%tmp1, %add)
  //
  // Trunc to i32.
  if (N->getValueType(0) == MVT::i32) {
    // Trunc from i64.
    if (Shift.getNode()->getValueType(0) == MVT::i64) {
      // Trunc child is logical shift right.
      if (Shift.getOpcode() != ISD::SRL) {
        return SelectCode(N);
      }

      SDValue ShiftOp0 = Shift.getOperand(0);
      SDValue ShiftOp1 = Shift.getOperand(1);

      // Shift by const 32
      if (ShiftOp1.getOpcode() != ISD::Constant) {
        return SelectCode(N);
      }

      int32_t ShiftConst =
        cast<ConstantSDNode>(ShiftOp1.getNode())->getSExtValue();
      if (ShiftConst != 32) {
        return SelectCode(N);
      }

      // Shifting a i64 signed multiply
      SDValue Mul = ShiftOp0;
      if (Mul.getOpcode() != ISD::MUL) {
        return SelectCode(N);
      }

      SDValue MulOp0 = Mul.getOperand(0);
      SDValue MulOp1 = Mul.getOperand(1);

      SDValue OP0;
      SDValue OP1;

      // Handle sign_extend and sextload
      if (MulOp0.getOpcode() == ISD::SIGN_EXTEND) {
        SDValue Sext0 = MulOp0.getOperand(0);
        if (Sext0.getNode()->getValueType(0) != MVT::i32) {
          return SelectCode(N);
        }

        OP0 = Sext0;
      } else if (MulOp0.getOpcode() == ISD::LOAD) {
        LoadSDNode *LD = cast<LoadSDNode>(MulOp0.getNode());
        if (LD->getMemoryVT() != MVT::i32 ||
            LD->getExtensionType() != ISD::SEXTLOAD ||
            LD->getAddressingMode() != ISD::UNINDEXED) {
          return SelectCode(N);
        }

        SDValue Chain = LD->getChain();
        SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
        OP0 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
                                              MVT::Other,
                                              LD->getBasePtr(),
                                              TargetConst0, Chain), 0);
      } else {
        return SelectCode(N);
      }

      // Same goes for the second operand.
      if (MulOp1.getOpcode() == ISD::SIGN_EXTEND) {
        SDValue Sext1 = MulOp1.getOperand(0);
        if (Sext1.getNode()->getValueType(0) != MVT::i32)
          return SelectCode(N);

        OP1 = Sext1;
      } else if (MulOp1.getOpcode() == ISD::LOAD) {
        LoadSDNode *LD = cast<LoadSDNode>(MulOp1.getNode());
        if (LD->getMemoryVT() != MVT::i32 ||
            LD->getExtensionType() != ISD::SEXTLOAD ||
            LD->getAddressingMode() != ISD::UNINDEXED) {
          return SelectCode(N);
        }

        SDValue Chain = LD->getChain();
        SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
        OP1 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
                                              MVT::Other,
                                              LD->getBasePtr(),
                                              TargetConst0, Chain), 0);
      } else {
        return SelectCode(N);
      }

      // Generate a mpy instruction.
      SDNode *Result = CurDAG->getMachineNode(Hexagon::MPY, dl, MVT::i32,
                                              OP0, OP1);
      ReplaceUses(N, Result);
      return Result;
    }
  }

  return SelectCode(N);
}

SDNode *HexagonDAGToDAGISel::SelectSHL(SDNode *N) {
  DebugLoc dl = N->getDebugLoc();
  if (N->getValueType(0) == MVT::i32) {
    SDValue Shl_0 = N->getOperand(0);
    SDValue Shl_1 = N->getOperand(1);
    // RHS is const.
    if (Shl_1.getOpcode() == ISD::Constant) {
      if (Shl_0.getOpcode() == ISD::MUL) {
        SDValue Mul_0 = Shl_0.getOperand(0); // Val
        SDValue Mul_1 = Shl_0.getOperand(1); // Const
        // RHS of mul is const.
        if (Mul_1.getOpcode() == ISD::Constant) {
          int32_t ShlConst =
            cast<ConstantSDNode>(Shl_1.getNode())->getSExtValue();
          int32_t MulConst =
            cast<ConstantSDNode>(Mul_1.getNode())->getSExtValue();
          int32_t ValConst = MulConst << ShlConst;
          SDValue Val = CurDAG->getTargetConstant(ValConst,
                                                  MVT::i32);
          if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Val.getNode()))
            if (isInt<9>(CN->getSExtValue())) {
              SDNode* Result =
                CurDAG->getMachineNode(Hexagon::MPYI_ri, dl,
                                       MVT::i32, Mul_0, Val);
              ReplaceUses(N, Result);
              return Result;
            }

        }
      } else if (Shl_0.getOpcode() == ISD::SUB) {
        SDValue Sub_0 = Shl_0.getOperand(0); // Const 0
        SDValue Sub_1 = Shl_0.getOperand(1); // Val
        if (Sub_0.getOpcode() == ISD::Constant) {
          int32_t SubConst =
            cast<ConstantSDNode>(Sub_0.getNode())->getSExtValue();
          if (SubConst == 0) {
            if (Sub_1.getOpcode() == ISD::SHL) {
              SDValue Shl2_0 = Sub_1.getOperand(0); // Val
              SDValue Shl2_1 = Sub_1.getOperand(1); // Const
              if (Shl2_1.getOpcode() == ISD::Constant) {
                int32_t ShlConst =
                  cast<ConstantSDNode>(Shl_1.getNode())->getSExtValue();
                int32_t Shl2Const =
                  cast<ConstantSDNode>(Shl2_1.getNode())->getSExtValue();
                int32_t ValConst = 1 << (ShlConst+Shl2Const);
                SDValue Val = CurDAG->getTargetConstant(-ValConst, MVT::i32);
                if (ConstantSDNode *CN =
                    dyn_cast<ConstantSDNode>(Val.getNode()))
                  if (isInt<9>(CN->getSExtValue())) {
                    SDNode* Result =
                      CurDAG->getMachineNode(Hexagon::MPYI_ri, dl, MVT::i32,
                                             Shl2_0, Val);
                    ReplaceUses(N, Result);
                    return Result;
                  }
              }
            }
          }
        }
      }
    }
  }
  return SelectCode(N);
}

//
// If there is an zero_extend followed an intrinsic in DAG (this means - the
// result of the intrinsic is predicate); convert the zero_extend to
// transfer instruction.
//
// Zero extend -> transfer is lowered here. Otherwise, zero_extend will be
// converted into a MUX as predicate registers defined as 1 bit in the
// compiler. Architecture defines them as 8-bit registers.
// We want to preserve all the lower 8-bits and, not just 1 LSB bit.
//
SDNode *HexagonDAGToDAGISel::SelectZeroExtend(SDNode *N) {
  DebugLoc dl = N->getDebugLoc();
  SDNode *IsIntrinsic = N->getOperand(0).getNode();
  if ((IsIntrinsic->getOpcode() == ISD::INTRINSIC_WO_CHAIN)) {
    unsigned ID =
      cast<ConstantSDNode>(IsIntrinsic->getOperand(0))->getZExtValue();
    if (doesIntrinsicReturnPredicate(ID)) {
      // Now we need to differentiate target data types.
      if (N->getValueType(0) == MVT::i64) {
        // Convert the zero_extend to Rs = Pd followed by COMBINE_rr(0,Rs).
        SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
        SDNode *Result_1 = CurDAG->getMachineNode(Hexagon::TFR_RsPd, dl,
                                                  MVT::i32,
                                                  SDValue(IsIntrinsic, 0));
        SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl,
                                                  MVT::i32,
                                                  TargetConst0);
        SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl,
                                                  MVT::i64, MVT::Other,
                                                  SDValue(Result_2, 0),
                                                  SDValue(Result_1, 0));
        ReplaceUses(N, Result_3);
        return Result_3;
      }
      if (N->getValueType(0) == MVT::i32) {
        // Convert the zero_extend to Rs = Pd
        SDNode* RsPd = CurDAG->getMachineNode(Hexagon::TFR_RsPd, dl,
                                              MVT::i32,
                                              SDValue(IsIntrinsic, 0));
        ReplaceUses(N, RsPd);
        return RsPd;
      }
      llvm_unreachable("Unexpected value type");
    }
  }
  return SelectCode(N);
}

//
// Checking for intrinsics which have predicate registers as operand(s)
// and lowering to the actual intrinsic.
//
SDNode *HexagonDAGToDAGISel::SelectIntrinsicWOChain(SDNode *N) {
  DebugLoc dl = N->getDebugLoc();
  unsigned ID = cast<ConstantSDNode>(N->getOperand(0))->getZExtValue();
  unsigned IntrinsicWithPred = doesIntrinsicContainPredicate(ID);

  // We are concerned with only those intrinsics that have predicate registers
  // as at least one of the operands.
  if (IntrinsicWithPred) {
    SmallVector<SDValue, 8> Ops;
    const MCInstrDesc &MCID = TII->get(IntrinsicWithPred);
    const TargetRegisterInfo *TRI = TM.getRegisterInfo();

    // Iterate over all the operands of the intrinsics.
    // For PredRegs, do the transfer.
    // For Double/Int Regs, just preserve the value
    // For immediates, lower it.
    for (unsigned i = 1; i < N->getNumOperands(); ++i) {
      SDNode *Arg = N->getOperand(i).getNode();
      const TargetRegisterClass *RC = TII->getRegClass(MCID, i, TRI, *MF);

      if (RC == &Hexagon::IntRegsRegClass ||
          RC == &Hexagon::DoubleRegsRegClass) {
        Ops.push_back(SDValue(Arg, 0));
      } else if (RC == &Hexagon::PredRegsRegClass) {
        // Do the transfer.
        SDNode *PdRs = CurDAG->getMachineNode(Hexagon::TFR_PdRs, dl, MVT::i1,
                                              SDValue(Arg, 0));
        Ops.push_back(SDValue(PdRs,0));
      } else if (RC == NULL && (dyn_cast<ConstantSDNode>(Arg) != NULL)) {
        // This is immediate operand. Lower it here making sure that we DO have
        // const SDNode for immediate value.
        int32_t Val = cast<ConstantSDNode>(Arg)->getSExtValue();
        SDValue SDVal = CurDAG->getTargetConstant(Val, MVT::i32);
        Ops.push_back(SDVal);
      } else {
        llvm_unreachable("Unimplemented");
      }
    }
    EVT ReturnValueVT = N->getValueType(0);
    SDNode *Result = CurDAG->getMachineNode(IntrinsicWithPred, dl,
                                            ReturnValueVT, Ops);
    ReplaceUses(N, Result);
    return Result;
  }
  return SelectCode(N);
}

//
// Map floating point constant values.
//
SDNode *HexagonDAGToDAGISel::SelectConstantFP(SDNode *N) {
  DebugLoc dl = N->getDebugLoc();
  ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N);
  APFloat APF = CN->getValueAPF();
  if (N->getValueType(0) == MVT::f32) {
    return CurDAG->getMachineNode(Hexagon::TFRI_f, dl, MVT::f32,
              CurDAG->getTargetConstantFP(APF.convertToFloat(), MVT::f32));
  }
  else if (N->getValueType(0) == MVT::f64) {
    return CurDAG->getMachineNode(Hexagon::CONST64_Float_Real, dl, MVT::f64,
              CurDAG->getTargetConstantFP(APF.convertToDouble(), MVT::f64));
  }

  return SelectCode(N);
}

//
// Map predicate true (encoded as -1 in LLVM) to a XOR.
//
SDNode *HexagonDAGToDAGISel::SelectConstant(SDNode *N) {
  DebugLoc dl = N->getDebugLoc();
  if (N->getValueType(0) == MVT::i1) {
    SDNode* Result;
    int32_t Val = cast<ConstantSDNode>(N)->getSExtValue();
    if (Val == -1) {
      // Create the IntReg = 1 node.
      SDNode* IntRegTFR =
        CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32,
                               CurDAG->getTargetConstant(0, MVT::i32));

      // Pd = IntReg
      SDNode* Pd = CurDAG->getMachineNode(Hexagon::TFR_PdRs, dl, MVT::i1,
                                          SDValue(IntRegTFR, 0));

      // not(Pd)
      SDNode* NotPd = CurDAG->getMachineNode(Hexagon::NOT_p, dl, MVT::i1,
                                             SDValue(Pd, 0));

      // xor(not(Pd))
      Result = CurDAG->getMachineNode(Hexagon::XOR_pp, dl, MVT::i1,
                                      SDValue(Pd, 0), SDValue(NotPd, 0));

      // We have just built:
      // Rs = Pd
      // Pd = xor(not(Pd), Pd)

      ReplaceUses(N, Result);
      return Result;
    }
  }

  return SelectCode(N);
}

//
// Map add followed by a asr -> asr +=.
//
SDNode *HexagonDAGToDAGISel::SelectAdd(SDNode *N) {
  DebugLoc dl = N->getDebugLoc();
  if (N->getValueType(0) != MVT::i32) {
    return SelectCode(N);
  }
  // Identify nodes of the form: add(asr(...)).
  SDNode* Src1 = N->getOperand(0).getNode();
  if (Src1->getOpcode() != ISD::SRA || !Src1->hasOneUse()
      || Src1->getValueType(0) != MVT::i32) {
    return SelectCode(N);
  }

  // Build Rd = Rd' + asr(Rs, Rt). The machine constraints will ensure that
  // Rd and Rd' are assigned to the same register
  SDNode* Result = CurDAG->getMachineNode(Hexagon::ASR_ADD_rr, dl, MVT::i32,
                                          N->getOperand(1),
                                          Src1->getOperand(0),
                                          Src1->getOperand(1));
  ReplaceUses(N, Result);

  return Result;
}

SDNode *HexagonDAGToDAGISel::Select(SDNode *N) {
  if (N->isMachineOpcode()) {
    N->setNodeId(-1);
    return NULL;   // Already selected.
  }

  switch (N->getOpcode()) {
  case ISD::Constant:
    return SelectConstant(N);

  case ISD::ConstantFP:
    return SelectConstantFP(N);

  case ISD::ADD:
    return SelectAdd(N);

  case ISD::SHL:
    return SelectSHL(N);

  case ISD::LOAD:
    return SelectLoad(N);

  case ISD::STORE:
    return SelectStore(N);

  case ISD::SELECT:
    return SelectSelect(N);

  case ISD::TRUNCATE:
    return SelectTruncate(N);

  case ISD::MUL:
    return SelectMul(N);

  case ISD::ZERO_EXTEND:
    return SelectZeroExtend(N);

  case ISD::INTRINSIC_WO_CHAIN:
    return SelectIntrinsicWOChain(N);
  }

  return SelectCode(N);
}

//
// Hexagon_TODO: Five functions for ADDRri?! Surely there must be a better way
// to define these instructions.
//
bool HexagonDAGToDAGISel::SelectADDRri(SDValue& Addr, SDValue &Base,
                                       SDValue &Offset) {
  if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
      Addr.getOpcode() == ISD::TargetGlobalAddress)
    return false;  // Direct calls.

  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
    Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
    Offset = CurDAG->getTargetConstant(0, MVT::i32);
    return true;
  }
  Base = Addr;
  Offset = CurDAG->getTargetConstant(0, MVT::i32);
  return true;
}

bool HexagonDAGToDAGISel::SelectADDRriS11_0(SDValue& Addr, SDValue &Base,
                                            SDValue &Offset) {
  if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
      Addr.getOpcode() == ISD::TargetGlobalAddress)
    return false;  // Direct calls.

  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
    Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
    Offset = CurDAG->getTargetConstant(0, MVT::i32);
    return (IsS11_0_Offset(Offset.getNode()));
  }
  Base = Addr;
  Offset = CurDAG->getTargetConstant(0, MVT::i32);
  return (IsS11_0_Offset(Offset.getNode()));
}

bool HexagonDAGToDAGISel::SelectADDRriS11_1(SDValue& Addr, SDValue &Base,
                                            SDValue &Offset) {
  if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
      Addr.getOpcode() == ISD::TargetGlobalAddress)
    return false;  // Direct calls.

  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
    Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
    Offset = CurDAG->getTargetConstant(0, MVT::i32);
    return (IsS11_1_Offset(Offset.getNode()));
  }
  Base = Addr;
  Offset = CurDAG->getTargetConstant(0, MVT::i32);
  return (IsS11_1_Offset(Offset.getNode()));
}

bool HexagonDAGToDAGISel::SelectADDRriS11_2(SDValue& Addr, SDValue &Base,
                                            SDValue &Offset) {
  if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
      Addr.getOpcode() == ISD::TargetGlobalAddress)
    return false;  // Direct calls.

  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
    Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
    Offset = CurDAG->getTargetConstant(0, MVT::i32);
    return (IsS11_2_Offset(Offset.getNode()));
  }
  Base = Addr;
  Offset = CurDAG->getTargetConstant(0, MVT::i32);
  return (IsS11_2_Offset(Offset.getNode()));
}

bool HexagonDAGToDAGISel::SelectADDRriU6_0(SDValue& Addr, SDValue &Base,
                                            SDValue &Offset) {
  if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
      Addr.getOpcode() == ISD::TargetGlobalAddress)
    return false;  // Direct calls.

  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
    Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
    Offset = CurDAG->getTargetConstant(0, MVT::i32);
    return (IsU6_0_Offset(Offset.getNode()));
  }
  Base = Addr;
  Offset = CurDAG->getTargetConstant(0, MVT::i32);
  return (IsU6_0_Offset(Offset.getNode()));
}

bool HexagonDAGToDAGISel::SelectADDRriU6_1(SDValue& Addr, SDValue &Base,
                                            SDValue &Offset) {
  if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
      Addr.getOpcode() == ISD::TargetGlobalAddress)
    return false;  // Direct calls.

  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
    Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
    Offset = CurDAG->getTargetConstant(0, MVT::i32);
    return (IsU6_1_Offset(Offset.getNode()));
  }
  Base = Addr;
  Offset = CurDAG->getTargetConstant(0, MVT::i32);
  return (IsU6_1_Offset(Offset.getNode()));
}

bool HexagonDAGToDAGISel::SelectADDRriU6_2(SDValue& Addr, SDValue &Base,
                                            SDValue &Offset) {
  if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
      Addr.getOpcode() == ISD::TargetGlobalAddress)
    return false;  // Direct calls.

  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
    Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
    Offset = CurDAG->getTargetConstant(0, MVT::i32);
    return (IsU6_2_Offset(Offset.getNode()));
  }
  Base = Addr;
  Offset = CurDAG->getTargetConstant(0, MVT::i32);
  return (IsU6_2_Offset(Offset.getNode()));
}

bool HexagonDAGToDAGISel::SelectMEMriS11_2(SDValue& Addr, SDValue &Base,
                                           SDValue &Offset) {

  if (Addr.getOpcode() != ISD::ADD) {
    return(SelectADDRriS11_2(Addr, Base, Offset));
  }

  return SelectADDRriS11_2(Addr, Base, Offset);
}

bool HexagonDAGToDAGISel::SelectADDRriS11_3(SDValue& Addr, SDValue &Base,
                                            SDValue &Offset) {
  if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
      Addr.getOpcode() == ISD::TargetGlobalAddress)
    return false;  // Direct calls.

  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
    Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
    Offset = CurDAG->getTargetConstant(0, MVT::i32);
    return (IsS11_3_Offset(Offset.getNode()));
  }
  Base = Addr;
  Offset = CurDAG->getTargetConstant(0, MVT::i32);
  return (IsS11_3_Offset(Offset.getNode()));
}

bool HexagonDAGToDAGISel::SelectADDRrr(SDValue &Addr, SDValue &R1,
                                       SDValue &R2) {
  if (Addr.getOpcode() == ISD::FrameIndex) return false;
  if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
      Addr.getOpcode() == ISD::TargetGlobalAddress)
    return false;  // Direct calls.

  if (Addr.getOpcode() == ISD::ADD) {
    if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))
      if (isInt<13>(CN->getSExtValue()))
        return false;  // Let the reg+imm pattern catch this!
    R1 = Addr.getOperand(0);
    R2 = Addr.getOperand(1);
    return true;
  }

  R1 = Addr;

  return true;
}

// Handle generic address case. It is accessed from inlined asm =m constraints,
// which could have any kind of pointer.
bool HexagonDAGToDAGISel::SelectAddr(SDNode *Op, SDValue Addr,
                                          SDValue &Base, SDValue &Offset) {
  if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
      Addr.getOpcode() == ISD::TargetGlobalAddress)
    return false;  // Direct calls.

  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
    Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
    Offset = CurDAG->getTargetConstant(0, MVT::i32);
    return true;
  }

  if (Addr.getOpcode() == ISD::ADD) {
    Base = Addr.getOperand(0);
    Offset = Addr.getOperand(1);
    return true;
  }

  Base = Addr;
  Offset = CurDAG->getTargetConstant(0, MVT::i32);
  return true;
}

bool HexagonDAGToDAGISel::
SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode,
                             std::vector<SDValue> &OutOps) {
  SDValue Op0, Op1;

  switch (ConstraintCode) {
  case 'o':   // Offsetable.
  case 'v':   // Not offsetable.
  default: return true;
  case 'm':   // Memory.
    if (!SelectAddr(Op.getNode(), Op, Op0, Op1))
      return true;
    break;
  }

  OutOps.push_back(Op0);
  OutOps.push_back(Op1);
  return false;
}

bool HexagonDAGToDAGISel::isConstExtProfitable(SDNode *N) const {
  unsigned UseCount = 0;
  for (SDNode::use_iterator I = N->use_begin(), E = N->use_end(); I != E; ++I) {
    UseCount++;
  }

  return (UseCount <= 1);

}

//===--------------------------------------------------------------------===//
// Return 'true' if use count of the global address is below threshold.
//===--------------------------------------------------------------------===//
bool HexagonDAGToDAGISel::hasNumUsesBelowThresGA(SDNode *N) const {
  assert(N->getOpcode() == ISD::TargetGlobalAddress &&
         "Expecting a target global address");

  // Always try to fold the address.
  if (TM.getOptLevel() == CodeGenOpt::Aggressive)
    return true;

  GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(N);
  DenseMap<const GlobalValue *, unsigned>::const_iterator GI =
    GlobalAddressUseCountMap.find(GA->getGlobal());

  if (GI == GlobalAddressUseCountMap.end())
    return false;

  return GI->second <= MaxNumOfUsesForConstExtenders;
}

//===--------------------------------------------------------------------===//
// Return true if the non GP-relative global address can be folded.
//===--------------------------------------------------------------------===//
inline bool HexagonDAGToDAGISel::foldGlobalAddress(SDValue &N, SDValue &R) {
  return foldGlobalAddressImpl(N, R, false);
}

//===--------------------------------------------------------------------===//
// Return true if the GP-relative global address can be folded.
//===--------------------------------------------------------------------===//
inline bool HexagonDAGToDAGISel::foldGlobalAddressGP(SDValue &N, SDValue &R) {
  return foldGlobalAddressImpl(N, R, true);
}

//===--------------------------------------------------------------------===//
// Fold offset of the global address if number of uses are below threshold.
//===--------------------------------------------------------------------===//
bool HexagonDAGToDAGISel::foldGlobalAddressImpl(SDValue &N, SDValue &R,
                                                bool ShouldLookForGP) {
  if (N.getOpcode() == ISD::ADD) {
    SDValue N0 = N.getOperand(0);
    SDValue N1 = N.getOperand(1);
    if ((ShouldLookForGP && (N0.getOpcode() == HexagonISD::CONST32_GP)) ||
        (!ShouldLookForGP && (N0.getOpcode() == HexagonISD::CONST32))) {
      ConstantSDNode *Const = dyn_cast<ConstantSDNode>(N1);
      GlobalAddressSDNode *GA =
        dyn_cast<GlobalAddressSDNode>(N0.getOperand(0));

      if (Const && GA &&
          (GA->getOpcode() == ISD::TargetGlobalAddress)) {
        if ((N0.getOpcode() == HexagonISD::CONST32) &&
                !hasNumUsesBelowThresGA(GA))
            return false;
        R = CurDAG->getTargetGlobalAddress(GA->getGlobal(),
                                          Const->getDebugLoc(),
                                          N.getValueType(),
                                          GA->getOffset() +
                                          (uint64_t)Const->getSExtValue());
        return true;
      }
    }
  }
  return false;
}

redpajama_set_name: RedPajamaGithub


text:
Accenture and SAP Chosen by CenterPoint Energy to Develop Asset Analytics Solution to Take Advantage of the Internet of Things
Solution will support company's integration of information technology with operational technology
HOUSTON AND HANNOVER, Germany; Mar. 16, 2015 – Accenture (NYSE: ACN) and SAP SE (NYSE: SAP) have been selected by CenterPoint Energy to design, test and implement an asset analytics solution that supports CenterPoint Energy's strategy of integrating information technology (IT) with operational technology (OT). This will help improve management and maintenance of its transmission and distribution assets.
The announcement was made at CeBIT 2015, being held in Hannover, Germany, from March 16-20.
Developed by the Accenture and SAP Business Solutions Group, the IT-OT Integration Solution by Accenture and SAP for utilities is designed to combine business data (IT) with sensor data (OT), as well as external data feeds to manage the unified data model on the scalable SAP HANA® Cloud Platform.
"The advent of the Industrial Internet of Things means that our organization is generating enormous amounts of data ranging from our enterprise, operations, customer and control systems, right through to specific assets," said Gary Hayes, CIO and SVP from CenterPoint Energy. "We selected Accenture and SAP to help us harness this data to generate operational and cost benefits for our business, based on their experience in transmission and distribution services and their successful history in teaming on innovative digital projects."
CenterPoint Energy is establishing SAP HANA as a core component of its technology platform to bring together enterprise and operational data. Accenture will manage the project using its industry knowledge and business process experience in the utilities domain and providing asset analytic guidance, testing, development and systems integration services. SAP intends to develop the platform utilizing the SAP HANA platform and a prototype asset health application.
"With deeper insight into its asset base through analytics, CenterPoint Energy would be able to enhance its decision making capability. This would allow the company to further reduce asset risk and increase the efficiency of capital and operations and maintenance spending," said Kathy Sanders, Accenture Utilities West Market Lead. "Given the potential for adverse weather events in the Houston area, reliability is a critical issue for clients. This initiative will help CenterPoint Energy target its planned asset replacements in key areas. In addition, the solution would address industry-wide needs, harnessing digital technology and the power of the SAP HANA platform to improve the management of the transmission and distribution network."
"With the launch of the Accenture and SAP Business Solutions Group, we've made major strides in establishing the next-generation platform for combining business and sensor data onto the SAP HANA platform, which can benefit numerous asset-heavy industries," said Henry Bailey, global vice president, Utilities, SAP. "In particular, the IT-OT Integration Solution for utilities integrates grid operations and business information to repair, maintain and optimize critical infrastructure assets in a safe and secure manner."
As Accenture and SAP are further enhancing their joint efforts to build industry solutions in the Internet of Things space, the IT-OT Integration Solution is also being developed for other asset-heavy industries. Furthermore, additional solutions are under development for other industries, such as industrial equipment and automotive.
Accenture is a global management consulting, technology services and outsourcing company, with approximately 319,000 people serving clients in more than 120 countries. Combining unparalleled experience, comprehensive capabilities across all industries and business functions, and extensive research on the world's most successful companies, Accenture collaborates with clients to help them become high-performance businesses and governments. The company generated net revenues of US$30.0 billion for the fiscal year ended Aug. 31, 2014. Its home page is www.accenture.com.
About CenterPoint Energy
CenterPoint Energy, Inc., headquartered in Houston, Texas, is a domestic energy delivery company that includes electric transmission & distribution, natural gas distribution and energy services operations. The company serves more than five million metered customers primarily in Arkansas, Louisiana, Minnesota, Mississippi, Oklahoma, and Texas. The company also owns a 55.4 percent limited partner interest in Enable Midstream Partners, a publicly traded master limited partnership it jointly controls with OGE Energy Corp., which owns, operates and develops natural gas and crude oil infrastructure assets. With more than 7,400 employees, CenterPoint Energy and its predecessor companies have been in business for more than 140 years. For more information, visit the website at www.CenterPointEnergy.com.
As market leader in enterprise application software, SAP (NYSE: SAP) helps companies of all sizes and industries run better. From back office to boardroom, warehouse to storefront, desktop to mobile device – SAP empowers people and organizations to work together more efficiently and use business insight more effectively to stay ahead of the competition. SAP applications and services enable more than 282,000 customers to operate profitably, adapt continuously, and grow sustainably. For more information, visit www.sap.com.
Any statements contained in this document that are not historical facts are forward-looking statements as defined in the U.S. Private Securities Litigation Reform Act of 1995. Words such as "anticipate," "believe," "estimate," "expect," "forecast," "intend," "may," "plan," "project," "predict," "should" and "will" and similar expressions as they relate to SAP are intended to identify such forward-looking statements. SAP undertakes no obligation to publicly update or revise any forward-looking statements. All forward-looking statements are subject to various risks and uncertainties that could cause actual results to differ materially from expectations. The factors that could affect SAP's future financial results are discussed more fully in SAP's filings with the U.S. Securities and Exchange Commission ("SEC"), including SAP's most recent Annual Report on Form 20-F filed with the SEC. Readers are cautioned not to place undue reliance on these forward-looking statements, which speak only as of their dates.
© 2015 SAP SE. All rights reserved. SAP and other SAP products and services mentioned herein as well as their respective logos are trademarks or registered trademarks of SAP SE in Germany and other countries. Please see http://www.sap.com/corporate-en/legal/copyright/index.epx#trademark for additional trademark information and notices.
Guy Cantwell
guy.cantwell@accenture.com
Justyna Devraj
justyna.devraj@accenture.com
Jason Loesche
j.loesche@sap.com
SAP News Center press room; press@sap.com
Client Wins/New Contracts


~~Strong evidence is presented in the accompanying article that shows how this appears to be a prime regulator of inflammatory genes at multiple pathways and that it has or synthetic derivatives of it have the potential to be useful in inhibiting the inflammatory response for the treatment of cardiovascular diseases.
~~My choice for Molecule of the year, 2012 is Desmosterol. This molecule, which is a precursor of cholesterol is involved in maintaining homeostasis in a large number of tissues. While it plays a major role during mammalian brain development, it is important for regulation of inflammatory responses. Recent contributions made for the understanding of primary functions of this molecule have shown that maintaining desmosterol-cholesterol balance is necessary for homeostasis. It is also important in the control of a variety of human disorders.
~~Very interesting discovery of the close homolog of BACE1 which is involved in the production of beta-amyloid. BACE2 is actually a very strong beta-amyloid degrading enzyme. It thus represents a new and strong candidate for therapies to treat / prevent Alzheimer's disease.
~~This molecule provides hope for treatment of patients with neurological disorders like Alzheimer's and Down's.
~~Population studies have earlier shown an association of mutations in Nlgn3 to be associated with autism in various ethnic groups. Animal studies also validate the role of Nlgn3 mutations in causing autism- like phenotype indicating clearly that Nlgn3 is important as a cell adhesion molecule to maintain proper synapses.


Sales remain strong at Silverado Village in Placerville. The senior-focused community features a blended environment where you can own your own home and run the household, but get assistance and enjoy recreation and social activities if and when you want them.
Silverado Village in Placerville is a community of 113 residences offering single story homes from 1,207 to 1,590 sq. ft. Two of the model homes are open and ready to tour.
All homes at Silverado Village include amenities built around senior needs and feature everything from easy-to-use lever style door hardware and controls on all plumbing fixtures, lower set cabinets and microwaves for better accessibility, no-step walk-in showers, recessed lighting at all travel paths and emergency pull cords and remote pendants for enhanced peace of mind. These amenities are in addition to build features such as R-8 duct insulation, tankless hot water heaters and homes built 18% more efficient than California energy efficiency requirements.
This multi-level service approach allows for a smooth transition from the responsibilities of a larger property to a more comfortable, low maintenance home with the full menu of amenities and services available when needed or desired.
Silverado Village communities offer priority access to the Eskaton Lodge and the homeowner Village Center which includes a Bistro Cafe, water aerobics year round in the indoor heated pool and spa, a fully-equipped fitness center, billiards, multi-purpose room for arts, crafts and educational seminars and more.


text:
'I fell in love with the overall society — the organisation, biking culture, openness to change'
Originally from the seaside town of Ayvalık in Turkey, Ozan Ozavci is an assistant professor of trans-imperial history at the University of Utrecht. He says he's fallen in love with Dutch cycling culture and Old Amsterdam goat's cheese and would relish the opportunity to discuss politics with Thierry Baudet.
I ended up here because I started a job as a post-doctoral research fellow on a project on security history at Utrecht University. This was five years ago. The same year, I was offered a permanent contract by the university so I stayed.
I think when I first arrived in the Netherlands, I was an expat because I only planned to live here for about four years, which was the duration of my post-doctoral research.
Then I guess I became a lovepat. Not because I fell in love with a Dutch woman but because I fell in love with the overall society — the organisation, the biking culture, openness to change, Albert Heijn, and Utrecht, which is where I live. Living in Utrecht is like living in a village with the perks of a big city. It fits quite well with my personality. I feel like I'm constantly moving between being an expat, lovepat, immigrant, etc., which perhaps tells us that these terms don't really help describe our life trajectories.
I'm happy here. For the foreseeable future, I have no plans to live anywhere else. My mortgage also suggests that I'll be here for at least a few more decades.
Do you speak Dutch and how did you learn?
I do, but not to the level of sophistication I would want as a historian whose work is mostly about words, texts, and subtexts. I might need to do more. I first went to a language school here in Utrecht before I had private lessons that the university arranged for me and a number of other international staff. I also did language exchanges, and now I've moved back to private courses to improve my speaking. Writing and reading is a less difficult problem at this stage.
There are a lot of Dutch things that I would consider my favourites. I very much like the biking culture here and how the traffic is organised around it. It's something I've missed in the other countries I've lived in. I very much like Old Amsterdam goat's cheese. I would even dare to say that Dapp Frietwinkel on the Vinkenburgstraat in Utrecht is making the best fries in the world, in my experience. There is also local Utrecht beer like the ones from Brouwerij De Leckere. Those are some of my favourite ones, too.
But I think my favourite Dutch thing overall is the individuals that make up Dutch society. Having lived relatively easier lives compared to the peoples in other parts of the world, they are very nice and kind people. In my experience, they are very welcoming. They live their lives mostly in search of and in pursuit of what they call gezellig moments. This is what I believe makes them happy people. It creates a positive cycle. I've been impressed with this kindness and happiness, time and time again.
This is a difficult one. In the beginning, I made an active attempt to think and act more like the Dutch in my professional environment. One day, a colleague, one of the senior ones, told me, 'We want you here and we hired you, Ozan, so that you would offer us what the Dutch cannot.'
This triggered in me the importance of my non-Dutch or international identity at the university. I've come to think that it's my asset, and I've clung to it more and more. The courses I teach and the epistemological basis of my research, if I may be an academic for a second, are all connected to this.
On a daily basis, I've certainly become more punctual since I've moved here. I've started to eat sandwiches a lot more than before, and I've become more direct when I communicate my ideas and arguments. Sometimes I think I should be more direct though.
But in my eyes the real threshold of being Dutch is something that I deducted from an outstanding moment one day. In one of my first months in the Netherlands, I saw this young guy peeling an orange with both hands while riding his bike. He rode past my office. I consider myself good on a bike. I used to cycle to work when I lived in London and Manchester. Since I saw that guy, I think that being Dutch pertains also to the ability to peel an orange while riding a bike. I don't think I'll ever be able to do that.
As I mentioned earlier, I quite like Old Amsterdam goat's cheese. I would like to meet the inventor of it and thank him or her in person for all the moments of pleasure it's given me. That would be number one.
I've read a lot about and by Baruch Spinoza, the philosopher. He had an unassuming lifestyle and modesty. I would like to talk to him about the everyday conduct of life. That would be fascinating, so that's number two.
Number three, I don't know which of the two, but I would like to talk to either of the far right leaders. The more popular one these days is Thierry Baudet. I would like to ask him in a private conversation his sincere opinions about George Floyd, racial discrimination, which is a serious problem here in the Netherlands also, and see how he responds when I tell him about the emotional vocabulary he adopts in his politics that centre on negativity, differentiation of people, and exclusion of immigrants, especially non-white ones. It seems counterproductive in larger Dutch society.
Some of the defining characteristics of the Dutch are an openness to learning, to changing, and inclusion. I think the change towards a more inclusive and antithetic direction in the debate over Zwarte Piet exemplifies this. I would want to hear what he genuinely thinks about all this.
All of the major tourist attractions are fantastic, but I think to be able to really appreciate the Dutch culture and landscape, I would advise visitors to rent a bike and cycle into the countryside when the weather is good, and go somewhere between Utrecht and Amsterdam. The coast is also really nice. My favourite spot is Bergen aan Zee so far. Zuid Limburg is a great site, and it's worth exploring too.
Tell us something surprising you've found out about the Netherlands
Aside from the kindness of the people and their awe-inspiring cycling skills, I was surprised by the absence of the blending of cultures. White and non-white Dutch people tend to live in different compartments, especially in smaller cities.
Being from Turkey, I find it surprising that after a decades-long presence, the Turkish immigrant community here is still considered 'the Turkish community', not as Dutch. Perhaps consequently, they are much more closed and much more conservative than in Britain and France and certain parts of Turkey. They mostly live in their own shell.
I was also surprised by the two way racism. Not just the racism towards the Turkish or especially the Moroccan populations here, but also by the Turks towards the native Dutch. It was very evident from the moment I first arrived here that the community needs to have more inter-cultural dialogue and engagement.
Finally, I can say I was a bit surprised when I noticed on a few occasions that, even though the Dutch tend to be direct, frank, and speak their minds, which I appreciate, they usually don't like being on the receiving end of it.
It would be sad to think about because I'm happy here but, if I were to do that, I would walk around Utrecht one last time. Of all the Dutch towns I've been, this is where I feel the most at home, and it's the closest to my heart.
I would sit with the people I love here at my favourite spot, just outside the Muzieklokaal, which is by the water and you can see the Dom Tower and the boats passing by. We would also possibly cycle toward Oud Zuilen, which was my routine on the weekends when I first arrived in this country. It would be a nice, nostalgic way to say goodbye.
Dr. Ozavci will be publishing a book in 2021 titled Dangerous Gifts: Imperialism, Security and Civil Wars in the Levant 1798-1864. You can learn more about it via this link.
Ozan Ozavci was talking to Brandon Hartley


Bar Stools Sorrento Bar Stool Purple Images Scoop Bar Stool Throughout Sorrento Bar Stools Uploaded by Judge Mitchell on Saturday, November 11th, 2017 in category Bar Stools.
See also Stylish Breakfast Bar Stools White Sorrento Swivel Bar Stool In Sorrento Bar Stools from Bar Stools Topic.
Here we have another image Amisco Sorrento Swivel Stool Modern Comfortable Free Shipping In Sorrento Bar Stools featured under Bar Stools Sorrento Bar Stool Purple Images Scoop Bar Stool Throughout Sorrento Bar Stools. We hope you enjoyed it and if you want to download the pictures in high quality, simply right click the image and choose "Save As". Thanks for reading Bar Stools Sorrento Bar Stool Purple Images Scoop Bar Stool Throughout Sorrento Bar Stools.


Join Indexed I/O on July 13th, 2015 at LegalTech West Cost. We will be co-sponsoring a social hour and would love for you to swing by and say 'hi', drinks are on us!
Let us know you are coming by sending a quick message to sales@indexed.io.


Here at A&P Fencing we can supply you with the traditional mixture of ballast and cement which can be mixed as required with water to create concrete. We also have a variety of other bagged aggregates. We can also supply you with the increasingly popular rapid set post-mix, which you just add water to make and – as the name suggests – it sets in almost no time at all! We also offer building sand and concrete sand which can be used for many other garden projects. Check these out, along with our other bagged aggregates, listed below.
Here at A&P Fencing we understand that there's no one-size-fits-all when it comes to cement mixes, ballast and building sand. That's why we offer a wide range so you can find the perfect product for the job.
We supply a selection of products for various types of jobs and requirements and we are confident that you'll find everything you need to get the work done to a high level.
Our range of ballast, cement, building sand and other bagged aggregates are all listed above. They are available for fast delivery from our West Midlands depots to popular locations including Birmingham, Sutton Coldfield, Great Barr, Tamworth, Lichfield and more.


text:
SD8010 : Thomas Arrives at Bury
taken 3 years ago, near to Fishpool, Bury, Great Britain
Thomas Arrives at Bury
Thomas the Tank Engine pulls in to platform 4 at Bolton Street Station after passing beneath the Jubilee Way road bridge.
One of Britain's most famous and recognisable (albeit fictional!) steam locomotives, Thomas is a character from The Railway Series books by the Reverend Wilbert Awdry and his son, Christopher. Thomas first appeared in 1946 when he was the focus of the four short stories contained in the second book in the series, "Thomas the Tank Engine". He is a cheeky little engine and tries very hard to be a very useful. He became the most popular character in the series, and is the title character in the accompanying television spin-off series, Thomas & Friends. All of the locomotives in The Railway Series were based on prototypical engines; Thomas is based on the E2 Class of locomotives, the London Brighton and South Coast Railway 0-6-0 E2 with extended side tanks. He is easily identified by his No. 1 and bright blue colour. On this day, he was giving rides along the sidings between Bolton Street Station and the Baron Street works as part of the very popular "Day out with Thomas" on the East Lancashire Railway.
© Copyright David Dixon and licensed for reuse under this Creative Commons Licence.
Start a discussion on SD8010 Suggest an update to this image Contact the contributor
SD8010, 1498 images (more nearby )
David Dixon (find more nearby)
Monday, 1 May, 2017 (more nearby)
Monday, 8 May, 2017
Historic sites and artefacts City, Town centre Railways People, Events
Camera (from Tags)
Panasonic DMC-G7
OSGB36: SD 801 106 [100m precision]
OSGB36: SD 801 106
South-southwest (about 202 degrees)
Steam Locomotive Thomas the Tank Engine Day Out with Thomas The Railway Series Steam Railway Heritage Railway East Lancashire Railway ELR Steam Train Bridge
Image Type (about): geograph
This page has been viewed about 19 times.
· Bury Station [327]
· East Lancashire Railway [280]
· East Lancashire Railway's Station [187]


This image and 11 other of my portraits of ChengLong villagers will be included in a sound art exhibition by Yen-ting Hsu, entitled "Sounds Delicious".
Freshly harvested clams from an aquaculture pond in Cheng-long Village.
Two children caught playing cards in the temple.
Women who work outside wear these traditional hats that cover their entire head, shoulders and face no matter how hot. Staying white is preferable.


We appreciate that Urge Surfing might not be a technique that is used by every Youth AoD counsellor out there.
It also won't be used for every clients that walks through the doors, but there might be a few (of each) who wish to explore this further and give it a go, it might even be a young person who asks you to support them in learning more about it. So understanding Urge Surfing even at the most basic level is important.
What is Urge Surfing and how can it be used for those wising to withdraw or reduce their substance use? Some believe that urge surfing is a useful technique to help prevent slip ups and relapse. Some would say that an urge is a physical sensation to do something that is felt through out or in different parts of the body. They can start at any time, there is often no rhyme or reason as to why these sensations are felt. Sometimes there might be an external stimulus (such as a smell, taste or a feeling) that forces the urge into ones mind. If someone has capacity to let the urge ride itself out, they usually only last up to 20 or 30 minutes.
Unfortunately many people who use substances wish to alleviate the discomfort that the urge brings with it, by using their substance of choice. So what does that mean for those who wish to learn how to "Urge Surf" through the discomfort and reduce their use or cope with cravings and withdrawal?
If a person is able to notice when the urge first appears/ starts, notice how their body reacts to an urge, take note of the urge and where it is located in the body, isolate it and begin to understand it, begin to focus on breathing for 2 minutes, then focus on where the urge was in their body, acknowledge the changes in the urge and body, this is urge surfing.