llvm.org GIT mirror llvm / 63f9720
Fun x86 encoding tricks: when adding an immediate value of 128, use a SUB instruction instead of an ADD, because -128 can be encoded in an 8-bit signed immediate field, while +128 can't be. This avoids the need for a 32-bit immediate field in this case. A similar optimization applies to 64-bit adds with 0x80000000, with the 32-bit signed immediate field. To support this, teach tablegen how to handle 64-bit constants. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@57663 91177308-0d34-0410-b5e6-96231b3b80d8 Dan Gohman 10 years ago
14 changed file(s) with 98 addition(s) and 40 deletion(s). Raw diff Collapse all Expand all
7979 # set(CMAKE_VERBOSE_MAKEFILE true)
8080
8181 add_definitions( -D__STDC_LIMIT_MACROS )
82 add_definitions( -D__STDC_CONSTANT_MACROS )
8283
8384 if( LLVM_ON_UNIX )
8485 add_definitions( -DLLVM_ON_UNIX )
482482 endif
483483
484484 LD.Flags += -L$(LibDir) -L$(LLVMLibDir)
485 CPP.BaseFlags += -D_GNU_SOURCE -D__STDC_LIMIT_MACROS
485 CPP.BaseFlags += -D_GNU_SOURCE -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS
486486 # All -I flags should go here, so that they don't confuse llvm-config.
487487 CPP.Flags += $(sort -I$(PROJ_OBJ_DIR) -I$(PROJ_SRC_DIR) \
488488 $(patsubst %,-I%/include,\
5959 // sign extended field.
6060 return (int64_t)N->getZExtValue() == (int8_t)N->getZExtValue();
6161 }]>;
62
63 def i64immFFFFFFFF : PatLeaf<(i64 imm), [{
64 // i64immFFFFFFFF - True if this is a specific constant we can't write in
65 // tblgen files.
66 return N->getZExtValue() == 0x00000000FFFFFFFFULL;
67 }]>;
68
6962
7063 def sextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (sextloadi8 node:$ptr))>;
7164 def sextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (sextloadi16 node:$ptr))>;
13221315 // Some peepholes
13231316 //===----------------------------------------------------------------------===//
13241317
1318 // Odd encoding trick: -128 fits into an 8-bit immediate field while
1319 // +128 doesn't, so in this special case use a sub instead of an add.
1320 def : Pat<(add GR64:$src1, 128),
1321 (SUB64ri8 GR64:$src1, -128)>;
1322 def : Pat<(store (add (loadi64 addr:$dst), 128), addr:$dst),
1323 (SUB64mi8 addr:$dst, -128)>;
1324
1325 // The same trick applies for 32-bit immediate fields in 64-bit
1326 // instructions.
1327 def : Pat<(add GR64:$src1, 0x0000000080000000),
1328 (SUB64ri32 GR64:$src1, 0xffffffff80000000)>;
1329 def : Pat<(store (add (loadi64 addr:$dst), 0x00000000800000000), addr:$dst),
1330 (SUB64mi32 addr:$dst, 0xffffffff80000000)>;
1331
13251332 // r & (2^32-1) ==> movz
1326 def : Pat<(and GR64:$src, i64immFFFFFFFF),
1333 def : Pat<(and GR64:$src, 0x00000000FFFFFFFF),
13271334 (MOVZX64rr32 (i32 (EXTRACT_SUBREG GR64:$src, x86_subreg_32bit)))>;
13281335 // r & (2^16-1) ==> movz
13291336 def : Pat<(and GR64:$src, 0xffff),
29102910 // Some peepholes
29112911 //===----------------------------------------------------------------------===//
29122912
2913 // Odd encoding trick: -128 fits into an 8-bit immediate field while
2914 // +128 doesn't, so in this special case use a sub instead of an add.
2915 def : Pat<(add GR16:$src1, 128),
2916 (SUB16ri8 GR16:$src1, -128)>;
2917 def : Pat<(store (add (loadi16 addr:$dst), 128), addr:$dst),
2918 (SUB16mi8 addr:$dst, -128)>;
2919 def : Pat<(add GR32:$src1, 128),
2920 (SUB32ri8 GR32:$src1, -128)>;
2921 def : Pat<(store (add (loadi32 addr:$dst), 128), addr:$dst),
2922 (SUB32mi8 addr:$dst, -128)>;
2923
29132924 // r & (2^16-1) ==> movz
29142925 def : Pat<(and GR32:$src1, 0xffff),
29152926 (MOVZX32rr16 (i16 (EXTRACT_SUBREG GR32:$src1, x86_subreg_16bit)))>;
0 ; RUN: llvm-as < %s | llc -march=x86 > %t
1 ; RUN: not grep add %t
2 ; RUN: grep subl %t | count 1
3
4 ; The immediate can be encoded in a smaller way if the
5 ; instruction is a sub instead of an add.
6
7 define i32 @foo(i32 inreg %a) nounwind {
8 %b = add i32 %a, 128
9 ret i32 %b
10 }
0 ; RUN: llvm-as < %s | llc -march=x86-64 > %t
1 ; RUN: not grep add %t
2 ; RUN: grep subq %t | count 2
3
4 ; The immediate can be encoded in a smaller way if the
5 ; instruction is a sub instead of an add.
6
7 define i64 @foo(i64 inreg %a) nounwind {
8 %b = add i64 %a, 2147483648
9 ret i64 %b
10 }
11 define i64 @bar(i64 inreg %a) nounwind {
12 %b = add i64 %a, 128
13 ret i64 %b
14 }
None // RUN: tblgen %s | grep -- -65536
0 // RUN: tblgen %s | grep -- 4294901760
11
22 def X {
33 int Y = 0xFFFF0000;
733733 emitCode("int64_t CN"+utostr(CTmp)+" = cast("+
734734 RootName + ")->getSExtValue();");
735735
736 emitCheck("CN" + utostr(CTmp) + " == " +itostr(II->getValue()));
736 emitCheck("CN" + utostr(CTmp) + " == "
737 "INT64_C(" +itostr(II->getValue()) + ")");
737738 } else {
738739 #ifndef NDEBUG
739740 Child->dump();
3434 }
3535
3636 Init *BitRecTy::convertValue(IntInit *II) {
37 int Val = II->getValue();
37 int64_t Val = II->getValue();
3838 if (Val != 0 && Val != 1) return 0; // Only accept 0 or 1 for a bit!
3939
4040 return new BitInit(Val != 0);
115115 }
116116
117117 Init *IntRecTy::convertValue(BitsInit *BI) {
118 int Result = 0;
118 int64_t Result = 0;
119119 for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i)
120120 if (BitInit *Bit = dynamic_cast(BI->getBit(i))) {
121121 Result |= Bit->getValue() << i;
261261
262262 bool BitsInit::printInHex(std::ostream &OS) const {
263263 // First, attempt to convert the value into an integer value...
264 int Result = 0;
264 int64_t Result = 0;
265265 for (unsigned i = 0, e = getNumBits(); i != e; ++i)
266266 if (BitInit *Bit = dynamic_cast(getBit(i))) {
267267 Result |= Bit->getValue() << i;
337337 BitsInit *BI = new BitsInit(Bits.size());
338338
339339 for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
340 if (Bits[i] >= 32) {
340 if (Bits[i] >= 64) {
341341 delete BI;
342342 return 0;
343343 }
344 BI->setBit(i, new BitInit(Value & (1 << Bits[i])));
344 BI->setBit(i, new BitInit(Value & (INT64_C(1) << Bits[i])));
345345 }
346346 return BI;
347347 }
442442 IntInit *LHSi = dynamic_cast(LHS);
443443 IntInit *RHSi = dynamic_cast(RHS);
444444 if (LHSi && RHSi) {
445 int LHSv = LHSi->getValue(), RHSv = RHSi->getValue();
446 int Result;
445 int64_t LHSv = LHSi->getValue(), RHSv = RHSi->getValue();
446 int64_t Result;
447447 switch (getOpcode()) {
448448 default: assert(0 && "Bad opcode!");
449449 case SHL: Result = LHSv << RHSv; break;
450450 case SRA: Result = LHSv >> RHSv; break;
451 case SRL: Result = (unsigned)LHSv >> (unsigned)RHSv; break;
451 case SRL: Result = (uint64_t)LHSv >> (uint64_t)RHSv; break;
452452 }
453453 return new IntInit(Result);
454454 }
860860 }
861861
862862 /// getValueAsInt - This method looks up the specified field and returns its
863 /// value as an int, throwing an exception if the field does not exist or if
863 /// value as an int64_t, throwing an exception if the field does not exist or if
864864 /// the value is not the right type.
865865 ///
866 int Record::getValueAsInt(const std::string &FieldName) const {
866 int64_t Record::getValueAsInt(const std::string &FieldName) const {
867867 const RecordVal *R = getValue(FieldName);
868868 if (R == 0 || R->getValue() == 0)
869869 throw "Record `" + getName() + "' does not have a field named `" +
879879 /// its value as a vector of integers, throwing an exception if the field does
880880 /// not exist or if the value is not the right type.
881881 ///
882 std::vector>
882 std::vector64_t>
883883 Record::getValueAsListOfInts(const std::string &FieldName) const {
884884 ListInit *List = getValueAsListInit(FieldName);
885 std::vector> Ints;
885 std::vector64_t> Ints;
886886 for (unsigned i = 0; i < List->getSize(); i++) {
887887 if (IntInit *II = dynamic_cast(List->getElement(i))) {
888888 Ints.push_back(II->getValue());
564564 /// IntInit - 7 - Represent an initalization by a literal integer value.
565565 ///
566566 class IntInit : public Init {
567 int Value;
568 public:
569 explicit IntInit(int V) : Value(V) {}
570
571 int getValue() const { return Value; }
567 int64_t Value;
568 public:
569 explicit IntInit(int64_t V) : Value(V) {}
570
571 int64_t getValue() const { return Value; }
572572
573573 virtual Init *convertInitializerTo(RecTy *Ty) {
574574 return Ty->convertValue(this);
10811081 /// its value as a vector of integers, throwing an exception if the field does
10821082 /// not exist or if the value is not the right type.
10831083 ///
1084 std::vector> getValueAsListOfInts(const std::string &FieldName) const;
1084 std::vector64_t> getValueAsListOfInts(const std::string &FieldName) const;
10851085
10861086 /// getValueAsDef - This method looks up the specified field and returns its
10871087 /// value as a Record, throwing an exception if the field does not exist or if
10961096 bool getValueAsBit(const std::string &FieldName) const;
10971097
10981098 /// getValueAsInt - This method looks up the specified field and returns its
1099 /// value as an int, throwing an exception if the field does not exist or if
1100 /// the value is not the right type.
1101 ///
1102 int getValueAsInt(const std::string &FieldName) const;
1099 /// value as an int64_t, throwing an exception if the field does not exist or
1100 /// if the value is not the right type.
1101 ///
1102 int64_t getValueAsInt(const std::string &FieldName) const;
11031103
11041104 /// getValueAsDag - This method looks up the specified field and returns its
11051105 /// value as an Dag, throwing an exception if the field does not exist or if
421421 std::map, LessRecord> RegisterSuperRegs;
422422 std::map, LessRecord> RegisterAliases;
423423 std::map > > SubRegVectors;
424 typedef std::map>, LessRecord> DwarfRegNumsMapTy;
424 typedef std::map64_t>, LessRecord> DwarfRegNumsMapTy;
425425 DwarfRegNumsMapTy DwarfRegNums;
426426
427427 const std::vector &Regs = Target.getRegisters();
684684 unsigned maxLength = 0;
685685 for (unsigned i = 0, e = Registers.size(); i != e; ++i) {
686686 Record *Reg = Registers[i].TheDef;
687 std::vector> RegNums = Reg->getValueAsListOfInts("DwarfNumbers");
687 std::vector64_t> RegNums = Reg->getValueAsListOfInts("DwarfNumbers");
688688 maxLength = std::max((size_t)maxLength, RegNums.size());
689689 if (DwarfRegNums.count(Reg))
690690 cerr << "Warning: DWARF numbers for register " << getQualifiedName(Reg)
1919 #include
2020 #include
2121 #include
22 #include
2223 using namespace llvm;
2324
2425 TGLexer::TGLexer(MemoryBuffer *StartBuf) : CurLineNo(1), CurBuf(StartBuf) {
342343 if (CurPtr == NumStart)
343344 return ReturnError(CurPtr-2, "Invalid hexadecimal number");
344345
346 errno = 0;
345347 CurIntVal = strtoll(NumStart, 0, 16);
348 if (errno == EINVAL)
349 return ReturnError(CurPtr-2, "Invalid hexadecimal number");
350 if (errno == ERANGE) {
351 errno = 0;
352 CurIntVal = (int64_t)strtoull(NumStart, 0, 16);
353 if (errno == EINVAL)
354 return ReturnError(CurPtr-2, "Invalid hexadecimal number");
355 if (errno == ERANGE)
356 return ReturnError(CurPtr-2, "Hexadecimal number out of range");
357 }
346358 return tgtok::IntVal;
347359 } else if (CurPtr[0] == 'b') {
348360 ++CurPtr;
6161 const char *TokStart;
6262 tgtok::TokKind CurCode;
6363 std::string CurStrVal; // This is valid for ID, STRVAL, VARNAME, CODEFRAGMENT
64 int CurIntVal; // This is valid for INTVAL.
64 int64_t CurIntVal; // This is valid for INTVAL.
6565
6666 /// IncludeRec / IncludeStack - This captures the current set of include
6767 /// directives we are nested within.
9797 "This token doesn't have a string value");
9898 return CurStrVal;
9999 }
100 int getCurIntVal() const {
100 int64_t getCurIntVal() const {
101101 assert(CurCode == tgtok::IntVal && "This token isn't an integer");
102102 return CurIntVal;
103103 }
293293 TokError("expected integer or bitrange");
294294 return true;
295295 }
296 int Start = Lex.getCurIntVal();
297 int End;
296 int64_t Start = Lex.getCurIntVal();
297 int64_t End;
298298
299299 if (Start < 0)
300300 return TokError("invalid range, cannot be negative");
425425 TokError("expected integer in bits type");
426426 return 0;
427427 }
428 unsigned Val = Lex.getCurIntVal();
428 uint64_t Val = Lex.getCurIntVal();
429429 if (Lex.Lex() != tgtok::greater) { // Eat count.
430430 TokError("expected '>' at end of bits type");
431431 return 0;