mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-26 07:34:06 +00:00
Reapply 'ARM IAS: support .thumb_set'
Re-apply the change after it was reverted to do conflicts due to another change being reverted. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@204306 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
badf4cb75a
commit
9320b807aa
@ -472,18 +472,21 @@ uint64_t ELFObjectWriter::SymbolValue(MCSymbolData &Data,
|
||||
if (Symbol.isAbsolute() && Symbol.isVariable()) {
|
||||
if (const MCExpr *Value = Symbol.getVariableValue()) {
|
||||
int64_t IntValue;
|
||||
if (Value->EvaluateAsAbsolute(IntValue, Layout))
|
||||
return (uint64_t)IntValue;
|
||||
if (Value->EvaluateAsAbsolute(IntValue, Layout)) {
|
||||
if (Data.getFlags() & ELF_Other_ThumbFunc)
|
||||
return static_cast<uint64_t>(IntValue | 1);
|
||||
else
|
||||
return static_cast<uint64_t>(IntValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!Symbol.isInSection())
|
||||
return 0;
|
||||
|
||||
|
||||
if (Data.getFragment()) {
|
||||
if (Data.getFlags() & ELF_Other_ThumbFunc)
|
||||
return Layout.getSymbolOffset(&Data)+1;
|
||||
return Layout.getSymbolOffset(&Data) | 1;
|
||||
else
|
||||
return Layout.getSymbolOffset(&Data);
|
||||
}
|
||||
@ -578,6 +581,8 @@ void ELFObjectWriter::WriteSymbol(MCDataFragment *SymtabF,
|
||||
// Binding and Type share the same byte as upper and lower nibbles
|
||||
uint8_t Binding = MCELF::GetBinding(OrigData);
|
||||
uint8_t Type = mergeTypeForSet(MCELF::GetType(OrigData), MCELF::GetType(Data));
|
||||
if (OrigData.getFlags() & ELF_Other_ThumbFunc)
|
||||
Type = ELF::STT_FUNC;
|
||||
uint8_t Info = (Binding << ELF_STB_Shift) | (Type << ELF_STT_Shift);
|
||||
|
||||
// Other and Visibility share the same byte with Visibility using the lower
|
||||
@ -587,6 +592,8 @@ void ELFObjectWriter::WriteSymbol(MCDataFragment *SymtabF,
|
||||
Other |= Visibility;
|
||||
|
||||
uint64_t Value = SymbolValue(Data, Layout);
|
||||
if (OrigData.getFlags() & ELF_Other_ThumbFunc)
|
||||
Value |= 1;
|
||||
uint64_t Size = 0;
|
||||
|
||||
assert(!(Data.isCommon() && !Data.isExternal()));
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "llvm/MC/MCInst.h"
|
||||
#include "llvm/MC/MCInstrDesc.h"
|
||||
#include "llvm/MC/MCInstrInfo.h"
|
||||
#include "llvm/MC/MCObjectFileInfo.h"
|
||||
#include "llvm/MC/MCParser/MCAsmLexer.h"
|
||||
#include "llvm/MC/MCParser/MCAsmParser.h"
|
||||
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
|
||||
@ -41,6 +42,7 @@
|
||||
#include "llvm/MC/MCTargetAsmParser.h"
|
||||
#include "llvm/Support/ARMBuildAttributes.h"
|
||||
#include "llvm/Support/ARMEHABI.h"
|
||||
#include "llvm/Support/COFF.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/ELF.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
@ -229,6 +231,7 @@ class ARMAsmParser : public MCTargetAsmParser {
|
||||
bool parseDirectiveObjectArch(SMLoc L);
|
||||
bool parseDirectiveArchExtension(SMLoc L);
|
||||
bool parseDirectiveAlign(SMLoc L);
|
||||
bool parseDirectiveThumbSet(SMLoc L);
|
||||
|
||||
StringRef splitMnemonic(StringRef Mnemonic, unsigned &PredicationCode,
|
||||
bool &CarrySetting, unsigned &ProcessorIMod,
|
||||
@ -8030,6 +8033,8 @@ bool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {
|
||||
return parseDirectiveArchExtension(DirectiveID.getLoc());
|
||||
else if (IDVal == ".align")
|
||||
return parseDirectiveAlign(DirectiveID.getLoc());
|
||||
else if (IDVal == ".thumb_set")
|
||||
return parseDirectiveThumbSet(DirectiveID.getLoc());
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -9087,6 +9092,71 @@ bool ARMAsmParser::parseDirectiveAlign(SMLoc L) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// parseDirectiveThumbSet
|
||||
/// ::= .thumb_set name, value
|
||||
bool ARMAsmParser::parseDirectiveThumbSet(SMLoc L) {
|
||||
StringRef Name;
|
||||
if (Parser.parseIdentifier(Name)) {
|
||||
TokError("expected identifier after '.thumb_set'");
|
||||
Parser.eatToEndOfStatement();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getLexer().isNot(AsmToken::Comma)) {
|
||||
TokError("expected comma after name '" + Name + "'");
|
||||
Parser.eatToEndOfStatement();
|
||||
return false;
|
||||
}
|
||||
Lex();
|
||||
|
||||
const MCExpr *Value;
|
||||
if (Parser.parseExpression(Value)) {
|
||||
TokError("missing expression");
|
||||
Parser.eatToEndOfStatement();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
||||
TokError("unexpected token");
|
||||
Parser.eatToEndOfStatement();
|
||||
return false;
|
||||
}
|
||||
Lex();
|
||||
|
||||
MCSymbol *Alias = getContext().GetOrCreateSymbol(Name);
|
||||
if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(Value)) {
|
||||
MCSymbol *Sym = getContext().LookupSymbol(SRE->getSymbol().getName());
|
||||
if (!Sym->isDefined()) {
|
||||
getStreamer().EmitSymbolAttribute(Sym, MCSA_Global);
|
||||
getStreamer().EmitAssignment(Alias, Value);
|
||||
return false;
|
||||
}
|
||||
|
||||
const MCObjectFileInfo::Environment Format =
|
||||
getContext().getObjectFileInfo()->getObjectFileType();
|
||||
switch (Format) {
|
||||
case MCObjectFileInfo::IsCOFF: {
|
||||
char Type = COFF::IMAGE_SYM_DTYPE_FUNCTION << COFF::SCT_COMPLEX_TYPE_SHIFT;
|
||||
getStreamer().EmitCOFFSymbolType(Type);
|
||||
// .set values are always local in COFF
|
||||
getStreamer().EmitSymbolAttribute(Alias, MCSA_Local);
|
||||
break;
|
||||
}
|
||||
case MCObjectFileInfo::IsELF:
|
||||
getStreamer().EmitSymbolAttribute(Alias, MCSA_ELF_TypeFunction);
|
||||
break;
|
||||
case MCObjectFileInfo::IsMachO:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: set the function as being a thumb function via the assembler
|
||||
getStreamer().EmitThumbFunc(Alias);
|
||||
getStreamer().EmitAssignment(Alias, Value);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Force static initialization.
|
||||
extern "C" void LLVMInitializeARMAsmParser() {
|
||||
RegisterMCAsmParser<ARMAsmParser> X(TheARMTarget);
|
||||
|
43
test/MC/ARM/thumb_set-diagnostics.s
Normal file
43
test/MC/ARM/thumb_set-diagnostics.s
Normal file
@ -0,0 +1,43 @@
|
||||
@ RUN: not llvm-mc -triple armv7-eabi -o /dev/null 2>&1 %s | FileCheck %s
|
||||
|
||||
.syntax unified
|
||||
|
||||
.thumb
|
||||
|
||||
.thumb_set
|
||||
|
||||
@ CHECK: error: expected identifier after '.thumb_set'
|
||||
@ CHECK: .thumb_set
|
||||
@ CHECL: ^
|
||||
|
||||
.thumb_set ., 0x0b5e55ed
|
||||
|
||||
@ CHECK: error: expected identifier after '.thumb_set'
|
||||
@ CHECK: .thumb_set ., 0x0b5e55ed
|
||||
@ CHECK: ^
|
||||
|
||||
.thumb_set labelled, 0x1abe11ed
|
||||
.thumb_set invalid, :lower16:labelled
|
||||
|
||||
@ CHECK: error: unknown token in expression
|
||||
@ CHECK: .thumb_set invalid, :lower16:labelled
|
||||
@ CHECK: ^
|
||||
|
||||
.thumb_set missing_comma
|
||||
|
||||
@ CHECK: error: expected comma after name 'missing_comma'
|
||||
@ CHECK: .thumb_set missing_comma
|
||||
@ CHECK: ^
|
||||
|
||||
.thumb_set missing_expression,
|
||||
|
||||
@ CHECK: error: missing expression
|
||||
@ CHECK: .thumb_set missing_expression,
|
||||
@ CHECK: ^
|
||||
|
||||
.thumb_set trailer_trash, 0x11fe1e55,
|
||||
|
||||
@ CHECK: error: unexpected token
|
||||
@ CHECK: .thumb_set trailer_trash, 0x11fe1e55,
|
||||
@ CHECK: ^
|
||||
|
140
test/MC/ARM/thumb_set.s
Normal file
140
test/MC/ARM/thumb_set.s
Normal file
@ -0,0 +1,140 @@
|
||||
@ RUN: llvm-mc -triple armv7-eabi -filetype obj -o - %s | llvm-readobj -t \
|
||||
@ RUN: | FileCheck %s
|
||||
|
||||
.syntax unified
|
||||
|
||||
.arm
|
||||
|
||||
.type arm_func,%function
|
||||
arm_func:
|
||||
nop
|
||||
|
||||
.thumb_set alias_arm_func, arm_func
|
||||
|
||||
.thumb
|
||||
|
||||
.type thumb_func,%function
|
||||
.thumb_func
|
||||
thumb_func:
|
||||
nop
|
||||
|
||||
.thumb_set alias_thumb_func, thumb_func
|
||||
|
||||
.thumb_set seedless, 0x5eed1e55
|
||||
.thumb_set eggsalad, seedless + 0x87788358
|
||||
.thumb_set faceless, ~eggsalad + 0xe133c002
|
||||
|
||||
.thumb_set alias_undefined_data, badblood
|
||||
|
||||
.data
|
||||
|
||||
.type badblood,%object
|
||||
badblood:
|
||||
.long 0xbadb100d
|
||||
|
||||
.type bedazzle,%object
|
||||
bedazzle:
|
||||
.long 0xbeda221e
|
||||
|
||||
.text
|
||||
.thumb
|
||||
|
||||
.thumb_set alias_defined_data, bedazzle
|
||||
|
||||
.type alpha,%function
|
||||
alpha:
|
||||
nop
|
||||
|
||||
.type beta,%function
|
||||
beta:
|
||||
bkpt
|
||||
|
||||
.thumb_set beta, alpha
|
||||
|
||||
.thumb_set alias_undefined, undefined
|
||||
|
||||
@ CHECK: Symbol {
|
||||
@ CHECK: Name: alias_arm_func
|
||||
@ CHECK: Value: 0x1
|
||||
@ CHECK: Type: Function
|
||||
@ CHECK: }
|
||||
|
||||
@ CHECK: Symbol {
|
||||
@ CHECK: Name: alias_defined_data
|
||||
@ CHECK: Value: 0x5
|
||||
@ CHECK: Type: Function
|
||||
@ CHECK: }
|
||||
|
||||
@ CHECK: Symbol {
|
||||
@ CHECK: Name: alias_thumb_func
|
||||
@ CHECK: Value: 0x5
|
||||
@ CHECK: Type: Function
|
||||
@ CHECK: }
|
||||
|
||||
@ CHECK: Symbol {
|
||||
@ CHECK: Name: alias_undefined_data
|
||||
@ CHECK: Value: 0x0
|
||||
@ CHECK: Type: Object
|
||||
@ CHECK: }
|
||||
|
||||
@ CHECK: Symbol {
|
||||
@ CHECK: Name: alpha
|
||||
@ CHECK: Value: 0x6
|
||||
@ XFAIL-CHECK: Value: 0x7
|
||||
@ CHECK: Type: Function
|
||||
@ CHECK: }
|
||||
|
||||
@ CHECK: Symbol {
|
||||
@ CHECK: Name: arm_func
|
||||
@ CHECK: Value: 0x0
|
||||
@ CHECK: Type: Function
|
||||
@ CHECK: }
|
||||
|
||||
@ CHECK: Symbol {
|
||||
@ CHECK: Name: bedazzle
|
||||
@ CHECK: Value: 0x4
|
||||
@ CHECK: Type: Object
|
||||
@ CHECK: }
|
||||
|
||||
@ CHECK: Symbol {
|
||||
@ CHECK: Name: beta
|
||||
@ CHECK: Value: 0x7
|
||||
@ CHECK: Type: Function
|
||||
@ CHECK: }
|
||||
|
||||
@ CHECK: Symbol {
|
||||
@ CHECK: Name: eggsalad
|
||||
@ CHECK: Value: 0xE665A1AD
|
||||
@ CHECK: Type: Function
|
||||
@ CHECK: }
|
||||
|
||||
@ CHECK: Symbol {
|
||||
@ CHECK: Name: faceless
|
||||
@ CHECK: Value: 0xFACE1E55
|
||||
@ CHECK: Type: Function
|
||||
@ CHECK: }
|
||||
|
||||
@ CHECK: Symbol {
|
||||
@ CHECK: Name: seedless
|
||||
@ CHECK: Value: 0x5EED1E55
|
||||
@ CHECK: Type: Function
|
||||
@ CHECK: }
|
||||
|
||||
@ CHECK: Symbol {
|
||||
@ CHECK: Name: thumb_func
|
||||
@ CHECK: Value: 0x5
|
||||
@ CHECK: Type: Function
|
||||
@ CHECK: }
|
||||
|
||||
@ CHECK: Symbol {
|
||||
@ CHECK: Name: badblood
|
||||
@ CHECK: Value: 0x0
|
||||
@ CHECK: Type: Object
|
||||
@ CHECK: }
|
||||
|
||||
@ CHECK: Symbol {
|
||||
@ CHECK: Name: undefined
|
||||
@ CHECK: Value: 0x0
|
||||
@ CHECK: Type: None
|
||||
@ CHECK: }
|
||||
|
Loading…
x
Reference in New Issue
Block a user