From 4df21b14675954ba951ad118d1dc4a4021650078 Mon Sep 17 00:00:00 2001 From: Reed Kotler Date: Wed, 13 Nov 2013 04:37:52 +0000 Subject: [PATCH] Allow the code which returns the length for inline assembler to know specifically about the .space directive. This allows us to force large blocks of code to appear in test cases for things like constant islands without having to make giant test cases to force things like long branches to take effect. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@194555 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/Mips16InstrInfo.cpp | 48 +++++++++++++++++++++- lib/Target/Mips/Mips16InstrInfo.h | 2 + lib/Target/Mips/MipsConstantIslandPass.cpp | 5 ++- test/CodeGen/Mips/const6a.ll | 29 +++++++++++++ 4 files changed, 81 insertions(+), 3 deletions(-) create mode 100644 test/CodeGen/Mips/const6a.ll diff --git a/lib/Target/Mips/Mips16InstrInfo.cpp b/lib/Target/Mips/Mips16InstrInfo.cpp index dbad0a499fa..8edc0029bd2 100644 --- a/lib/Target/Mips/Mips16InstrInfo.cpp +++ b/lib/Target/Mips/Mips16InstrInfo.cpp @@ -10,7 +10,8 @@ // This file contains the Mips16 implementation of the TargetInstrInfo class. // //===----------------------------------------------------------------------===// - +#include +#include #include "Mips16InstrInfo.h" #include "InstPrinter/MipsInstPrinter.h" #include "MipsMachineFunction.h" @@ -20,6 +21,7 @@ #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/RegisterScavenging.h" +#include "llvm/MC/MCAsmInfo.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" @@ -495,3 +497,47 @@ bool Mips16InstrInfo::validImmediate(unsigned Opcode, unsigned Reg, } llvm_unreachable("unexpected Opcode in validImmediate"); } + +/// Measure the specified inline asm to determine an approximation of its +/// length. +/// Comments (which run till the next SeparatorString or newline) do not +/// count as an instruction. +/// Any other non-whitespace text is considered an instruction, with +/// multiple instructions separated by SeparatorString or newlines. +/// Variable-length instructions are not handled here; this function +/// may be overloaded in the target code to do that. +/// We implement the special case of the .space directive taking only an +/// integer argument, which is the size in bytes. This is used for creating +/// inline code spacing for testing purposes using inline assembly. +/// +unsigned Mips16InstrInfo::getInlineAsmLength(const char *Str, + const MCAsmInfo &MAI) const { + + + // Count the number of instructions in the asm. + bool atInsnStart = true; + unsigned Length = 0; + for (; *Str; ++Str) { + if (*Str == '\n' || strncmp(Str, MAI.getSeparatorString(), + strlen(MAI.getSeparatorString())) == 0) + atInsnStart = true; + if (atInsnStart && !std::isspace(static_cast(*Str))) { + if (strncmp(Str, ".space", 6)==0) { + char *EStr; int Sz; + Sz = strtol(Str+6, &EStr, 10); + while (isspace(*EStr)) ++EStr; + if (*EStr=='\0') { + DEBUG(dbgs() << "parsed .space " << Sz << '\n'); + return Sz; + } + } + Length += MAI.getMaxInstLength(); + atInsnStart = false; + } + if (atInsnStart && strncmp(Str, MAI.getCommentString(), + strlen(MAI.getCommentString())) == 0) + atInsnStart = false; + } + + return Length; +} diff --git a/lib/Target/Mips/Mips16InstrInfo.h b/lib/Target/Mips/Mips16InstrInfo.h index 118d258a2bb..d9a594b537a 100644 --- a/lib/Target/Mips/Mips16InstrInfo.h +++ b/lib/Target/Mips/Mips16InstrInfo.h @@ -108,6 +108,8 @@ public: void BuildAddiuSpImm (MachineBasicBlock &MBB, MachineBasicBlock::iterator I, int64_t Imm) const; + unsigned getInlineAsmLength(const char *Str, + const MCAsmInfo &MAI) const; private: virtual unsigned getAnalyzableBrOpc(unsigned Opc) const; diff --git a/lib/Target/Mips/MipsConstantIslandPass.cpp b/lib/Target/Mips/MipsConstantIslandPass.cpp index 16573644b93..c40b7fe39b8 100644 --- a/lib/Target/Mips/MipsConstantIslandPass.cpp +++ b/lib/Target/Mips/MipsConstantIslandPass.cpp @@ -25,6 +25,7 @@ #include "Mips.h" #include "MCTargetDesc/MipsBaseInfo.h" +#include "Mips16InstrInfo.h" #include "MipsMachineFunction.h" #include "MipsTargetMachine.h" #include "llvm/ADT/Statistic.h" @@ -237,7 +238,7 @@ namespace { bool IsPIC; unsigned ABI; const MipsSubtarget *STI; - const MipsInstrInfo *TII; + const Mips16InstrInfo *TII; MipsFunctionInfo *MFI; MachineFunction *MF; MachineConstantPool *MCP; @@ -359,7 +360,7 @@ bool MipsConstantIslands::runOnMachineFunction(MachineFunction &mf) { !MipsSubtarget::useConstantIslands()) { return false; } - TII = (const MipsInstrInfo*)MF->getTarget().getInstrInfo(); + TII = (const Mips16InstrInfo*)MF->getTarget().getInstrInfo(); MFI = MF->getInfo(); DEBUG(dbgs() << "constant island processing " << "\n"); // diff --git a/test/CodeGen/Mips/const6a.ll b/test/CodeGen/Mips/const6a.ll new file mode 100644 index 00000000000..8b402accc7d --- /dev/null +++ b/test/CodeGen/Mips/const6a.ll @@ -0,0 +1,29 @@ +; RUN: llc -mtriple=mipsel-linux-gnu -march=mipsel -mcpu=mips16 -soft-float -mips16-hard-float -relocation-model=pic -mips16-constant-islands < %s | FileCheck %s -check-prefix=load-relax1 + +; RUN: llc -mtriple=mipsel-linux-gnu -march=mipsel -mcpu=mips16 -soft-float -mips16-hard-float -relocation-model=pic -mips16-constant-islands < %s | FileCheck %s -check-prefix=load-relax + +; ModuleID = 'const6a.c' +target datalayout = "E-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32-S64" +target triple = "mips--linux-gnu" + +@i = common global i32 0, align 4 + +; Function Attrs: nounwind +define void @t() #0 { +entry: + store i32 -559023410, i32* @i, align 4 +; load-relax-NOT: lw ${{[0-9]+}}, $CPI0_0 # 16 bit inst +; load-relax1: lw ${{[0-9]+}}, $CPI0_0 +; load-relax: jrc $ra +; load-relax: .align 2 +; load-relax: $CPI0_0: +; load-relax: .4byte 3735943886 +; load-relax: .end t + call void asm sideeffect ".space 40000", ""() #1, !srcloc !1 + ret void +} + +attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="true" } +attributes #1 = { nounwind } + +!1 = metadata !{i32 121} -- 2.34.1