diff --git a/llvm/include/llvm/Target/Target.td b/llvm/include/llvm/Target/Target.td --- a/llvm/include/llvm/Target/Target.td +++ b/llvm/include/llvm/Target/Target.td @@ -1525,6 +1525,10 @@ // setting hasExtraDefRegAllocReq and hasExtraSrcRegAllocReq to 1 // for all opcodes if this flag is set to 0. int AllowRegisterRenaming = 0; + + // BitsPerByte - Specifies the size (in bits) of the smallest addressable + // unit in the target. Typically this is 8 bits, which is the default value. + int BitsPerByte = 8; } //===----------------------------------------------------------------------===// diff --git a/llvm/test/TableGen/GlobalISelEmitter-bits-per-byte.td b/llvm/test/TableGen/GlobalISelEmitter-bits-per-byte.td new file mode 100644 --- /dev/null +++ b/llvm/test/TableGen/GlobalISelEmitter-bits-per-byte.td @@ -0,0 +1,49 @@ +// RUN: llvm-tblgen -gen-global-isel -optimize-match-table=false -I %p/../../include -I %p/Common %s -o - < %s | FileCheck %s + +include "llvm/Target/Target.td" + +def MyTargetISA : InstrInfo; +def MyTarget : Target { + let InstructionSet = MyTargetISA; + let BitsPerByte = 16; +} + +class MyTargetGenericInstruction : GenericInstruction { + let Namespace = "MyTarget"; +} + +def R0 : Register<"r0"> { let Namespace = "MyTarget"; } +def GPR32 : RegisterClass<"MyTarget", [i32], 32, (add R0)>; +def GPR32Op : RegisterOperand; +def S0 : Register<"s0"> { let Namespace = "MyTarget"; } +def GPR16 : RegisterClass<"MyTarget", [i16], 16, (add S0)>; +def GPR16Op : RegisterOperand; + +class I Pat> + : Instruction { + let Namespace = "MyTarget"; + let OutOperandList = OOps; + let InOperandList = IOps; + let Pattern = Pat; +} + +def SEXTLOAD16 : I<(outs GPR32:$dst), + (ins GPR16:$src), []>; + +// CHECK: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2, +// CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_SEXTLOAD, +// CHECK-NEXT: GIM_CheckMemorySizeEqualTo, /*MI*/0, /*MMO*/0, /*Size*/1, +// CHECK-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(int64_t)AtomicOrdering::NotAtomic, +// CHECK-NEXT: // MIs[0] dst +// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, +// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, +// CHECK-NEXT: // MIs[0] src +// CHECK-NEXT: GIM_CheckPointerToAny, /*MI*/0, /*Op*/1, /*SizeInBits*/16, +// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/MyTarget::GPR16RegClassID, +// CHECK-NEXT: // (ld:{ *:[i32] } GPR16:{ *:[i16] }:$src)<><><> => (SEXTLOAD16:{ *:[i32] } GPR16:{ *:[i16] }:$src) +// CHECK-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/MyTarget::SEXTLOAD16, +// CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, +// CHECK-NEXT: // GIR_Coverage, 0, +// CHECK-NEXT: GIR_Done, +def : Pat<(i32 (sextloadi16 GPR16:$src)), + (SEXTLOAD16 GPR16:$src)>; diff --git a/llvm/utils/TableGen/CodeGenTarget.h b/llvm/utils/TableGen/CodeGenTarget.h --- a/llvm/utils/TableGen/CodeGenTarget.h +++ b/llvm/utils/TableGen/CodeGenTarget.h @@ -86,6 +86,10 @@ /// bool getAllowRegisterRenaming() const; + /// getBitsPerByte - Return the BitsPerByte int value for this target. + /// + int getBitsPerByte() const; + /// getAsmParser - Return the AssemblyParser definition for this target. /// Record *getAsmParser() const; diff --git a/llvm/utils/TableGen/CodeGenTarget.cpp b/llvm/utils/TableGen/CodeGenTarget.cpp --- a/llvm/utils/TableGen/CodeGenTarget.cpp +++ b/llvm/utils/TableGen/CodeGenTarget.cpp @@ -293,6 +293,10 @@ return TargetRec->getValueAsInt("AllowRegisterRenaming"); } +int CodeGenTarget::getBitsPerByte() const { + return TargetRec->getValueAsInt("BitsPerByte"); +} + /// getAsmParser - Return the AssemblyParser definition for this target. /// Record *CodeGenTarget::getAsmParser() const { diff --git a/llvm/utils/TableGen/GlobalISelEmitter.cpp b/llvm/utils/TableGen/GlobalISelEmitter.cpp --- a/llvm/utils/TableGen/GlobalISelEmitter.cpp +++ b/llvm/utils/TableGen/GlobalISelEmitter.cpp @@ -3812,11 +3812,10 @@ // MMO's work in bytes so we must take care of unusual types like i1 // don't round down. - unsigned MemSizeInBits = - llvm::alignTo(MemTyOrNone->get().getSizeInBits(), 8); - - InsnMatcher.addPredicate(0, - MemSizeInBits / 8); + unsigned MemSizeInBits = llvm::alignTo(MemTyOrNone->get().getSizeInBits(), + Target.getBitsPerByte()); + unsigned RoundedMemSize = MemSizeInBits / Target.getBitsPerByte(); + InsnMatcher.addPredicate(0, RoundedMemSize); return InsnMatcher; } }