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
This commit is contained in:
Reed Kotler 2013-11-13 04:37:52 +00:00
parent 950abf3933
commit 4df21b1467
4 changed files with 81 additions and 3 deletions

@ -10,7 +10,8 @@
// This file contains the Mips16 implementation of the TargetInstrInfo class.
//
//===----------------------------------------------------------------------===//
#include <ctype.h>
#include <stdlib.h>
#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<unsigned char>(*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;
}

@ -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;

@ -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<MipsFunctionInfo>();
DEBUG(dbgs() << "constant island processing " << "\n");
//

@ -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}