}
bool translateUnreachable(const User &U) { return true; }
+ bool translateSExt(const User &U) {
+ return translateCast(TargetOpcode::G_SEXT, U);
+ }
+
+ bool translateZExt(const User &U) {
+ return translateCast(TargetOpcode::G_ZEXT, U);
+ }
+
/// Translate return (ret) instruction.
/// The target needs to implement CallLowering::lowerReturn for
/// this to succeed.
bool translateFence(const User &U) { return false; }
bool translateAtomicCmpXchg(const User &U) { return false; }
bool translateAtomicRMW(const User &U) { return false; }
- bool translateSExt(const User &U) { return false; }
- bool translateZExt(const User &U) { return false; }
bool translateFPToUI(const User &U) { return false; }
bool translateFPToSI(const User &U) { return false; }
bool translateUIToFP(const User &U) { return false; }
//
//===----------------------------------------------------------------------===//
+//------------------------------------------------------------------------------
// Unary ops.
//------------------------------------------------------------------------------
let hasSideEffects = 0;
}
+// Sign extend the underlying scalar type of an operation, copying the sign bit
+// into the newly-created space.
+def G_SEXT : Instruction {
+ let OutOperandList = (outs unknown:$dst);
+ let InOperandList = (ins unknown:$src);
+ let hasSideEffects = 0;
+}
+
+// Zero extend the underlying scalar type of an operation, putting zero bits
+// into the newly-created space.
+def G_ZEXT : Instruction {
+ let OutOperandList = (outs unknown:$dst);
+ let InOperandList = (ins unknown:$src);
+ let hasSideEffects = 0;
+}
+
+
// Truncate the underlying scalar type of an operation. This is equivalent to
// G_EXTRACT for scalar types, but acts elementwise on vectors.
def G_TRUNC : Instruction {
let hasSideEffects = 0;
}
-//------------------------------------------------------------------------------
-// Unary ops.
-//------------------------------------------------------------------------------
-
def G_FRAME_INDEX : Instruction {
let OutOperandList = (outs unknown:$dst);
let InOperandList = (ins unknown:$src2);
/// Generic integer constant.
HANDLE_TARGET_OPCODE(G_CONSTANT)
+// Generic sign extend
+HANDLE_TARGET_OPCODE(G_SEXT)
+
+// Generic zero extend
+HANDLE_TARGET_OPCODE(G_ZEXT)
+
/// Generic BRANCH instruction. This is an unconditional branch.
HANDLE_TARGET_OPCODE(G_BR)
define i64 @test_reused_constant() {
ret i64 1
}
+
+; CHECK-LABEL: name: test_sext
+; CHECK: [[IN:%[0-9]+]](32) = COPY %w0
+; CHECK: [[RES:%[0-9]+]](64) = G_SEXT { s64, s32 } [[IN]]
+; CHECK: %x0 = COPY [[RES]]
+define i64 @test_sext(i32 %in) {
+ %res = sext i32 %in to i64
+ ret i64 %res
+}
+
+; CHECK-LABEL: name: test_zext
+; CHECK: [[IN:%[0-9]+]](32) = COPY %w0
+; CHECK: [[RES:%[0-9]+]](64) = G_ZEXT { s64, s32 } [[IN]]
+; CHECK: %x0 = COPY [[RES]]
+define i64 @test_zext(i32 %in) {
+ %res = zext i32 %in to i64
+ ret i64 %res
+}