From 9d20fa09eb806cd210d040e5e1e9b29c6e40e98e Mon Sep 17 00:00:00 2001 From: "Kazushi (Jam) Marukawa" Date: Mon, 6 Dec 2021 03:52:26 +0900 Subject: [PATCH] [VE] Support VE specific data directives in MC Support VE specific data directives, .word/.long/.llong, in MC layer. Reviewed By: simoll Differential Revision: https://reviews.llvm.org/D115120 --- llvm/lib/Target/VE/AsmParser/VEAsmParser.cpp | 35 +++++++++++++++++++++ llvm/test/MC/VE/data-size-error.s | 36 +++++++++++++++++++++ llvm/test/MC/VE/data.s | 47 ++++++++++++++++++++++++++++ 3 files changed, 118 insertions(+) create mode 100644 llvm/test/MC/VE/data-size-error.s create mode 100644 llvm/test/MC/VE/data.s diff --git a/llvm/lib/Target/VE/AsmParser/VEAsmParser.cpp b/llvm/lib/Target/VE/AsmParser/VEAsmParser.cpp index 7e92e4b..fd9dc32 100644 --- a/llvm/lib/Target/VE/AsmParser/VEAsmParser.cpp +++ b/llvm/lib/Target/VE/AsmParser/VEAsmParser.cpp @@ -84,6 +84,8 @@ class VEAsmParser : public MCTargetAsmParser { StringRef splitMnemonic(StringRef Name, SMLoc NameLoc, OperandVector *Operands); + bool parseLiteralValues(unsigned Size, SMLoc L); + public: VEAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser, const MCInstrInfo &MII, const MCTargetOptions &Options) @@ -994,10 +996,43 @@ bool VEAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, } bool VEAsmParser::ParseDirective(AsmToken DirectiveID) { + std::string IDVal = DirectiveID.getIdentifier().lower(); + + // Defines VE specific directives. Reference is "Vector Engine Assembly + // Language Reference Manual": + // https://www.hpc.nec/documents/sdk/pdfs/VectorEngine-as-manual-v1.3.pdf + + // The .word is 4 bytes long on VE. + if (IDVal == ".word") + return parseLiteralValues(4, DirectiveID.getLoc()); + + // The .long is 8 bytes long on VE. + if (IDVal == ".long") + return parseLiteralValues(8, DirectiveID.getLoc()); + + // The .llong is 8 bytes long on VE. + if (IDVal == ".llong") + return parseLiteralValues(8, DirectiveID.getLoc()); + // Let the MC layer to handle other directives. return true; } +/// parseLiteralValues +/// ::= .word expression [, expression]* +/// ::= .long expression [, expression]* +/// ::= .llong expression [, expression]* +bool VEAsmParser::parseLiteralValues(unsigned Size, SMLoc L) { + auto parseOne = [&]() -> bool { + const MCExpr *Value; + if (getParser().parseExpression(Value)) + return true; + getParser().getStreamer().emitValue(Value, Size, L); + return false; + }; + return (parseMany(parseOne)); +} + /// Extract \code @lo32/@hi32/etc \endcode modifier from expression. /// Recursively scan the expression and check for VK_VE_HI32/LO32/etc /// symbol variants. If all symbols with modifier use the same diff --git a/llvm/test/MC/VE/data-size-error.s b/llvm/test/MC/VE/data-size-error.s new file mode 100644 index 0000000..0313944 --- /dev/null +++ b/llvm/test/MC/VE/data-size-error.s @@ -0,0 +1,36 @@ +# RUN: not llvm-mc -triple=ve -filetype=obj %s -o /dev/null 2>&1 | \ +# RUN: FileCheck %s + +.data +a: +.2byte 0xff5588 +.4byte 0xff5588aade +.8byte 0xff5588aadeadbeafde +.byte 0xff55 +.short 0xff5588 +.word 0xff5588aaff +.int 0xff5588aaff +.long 0xff5588aadeadbeafde +.quad 0xff5588aadeadbeafde +.llong 0xff5588aadeadbeafde + +# CHECK: data-size-error.s:6:8: error: out of range literal value +# CHECK-NEXT: .2byte 0xff5588 +# CHECK: data-size-error.s:7:8: error: out of range literal value +# CHECK-NEXT: .4byte 0xff5588aade +# CHECK: data-size-error.s:8:8: error: literal value out of range for directive +# CHECK-NEXT: .8byte 0xff5588aadeadbeafde +# CHECK: data-size-error.s:9:7: error: out of range literal value +# CHECK-NEXT: .byte 0xff55 +# CHECK: data-size-error.s:10:8: error: out of range literal value +# CHECK-NEXT: .short 0xff5588 +# CHECK: data-size-error.s:11:1: error: value evaluated as 1096651680511 is out of range. +# CHECK-NEXT: .word 0xff5588aaff +# CHECK: data-size-error.s:12:6: error: out of range literal value +# CHECK-NEXT: .int 0xff5588aaff +# CHECK: data-size-error.s:13:7: error: literal value out of range for directive +# CHECK-NEXT: .long 0xff5588aadeadbeafde +# CHECK: data-size-error.s:14:7: error: literal value out of range for directive +# CHECK-NEXT: .quad 0xff5588aadeadbeafde +# CHECK: data-size-error.s:15:8: error: literal value out of range for directive +# CHECK-NEXT: .llong 0xff5588aadeadbeafde diff --git a/llvm/test/MC/VE/data.s b/llvm/test/MC/VE/data.s new file mode 100644 index 0000000..f0ff830 --- /dev/null +++ b/llvm/test/MC/VE/data.s @@ -0,0 +1,47 @@ +# RUN: llvm-mc -triple=ve %s -o - | FileCheck %s +# RUN: llvm-mc -triple=ve -filetype=obj %s -o - | llvm-objdump -s - | \ +# RUN: FileCheck %s --check-prefix=OBJ + +.data +a: +.2byte 0xff55, 0x88aa +.4byte 0xff5588aa, 0xdeadbeaf +.8byte 0xff5588aadeadbeaf, 0xdeadbeafdeadbeaf +.byte 0xff, 0x55, 0x88 +.short 0xff55, 0x88aa +.word 0xff5588aa, 0xdeadbeaf +.int 0xff5588aa, 0xdeadbeaf +.long 0xff5588aadeadbeaf, 0xdeadbeafdeadbeaf +.quad 0xff5588aadeadbeaf, 0xdeadbeafdeadbeaf +.llong 0xff5588aadeadbeaf, 0xdeadbeafdeadbeaf + +# CHECK: .2byte 65365 +# CHECK-NEXT: .2byte 34986 +# CHECK-NEXT: .4byte 4283795626 +# CHECK-NEXT: .4byte 3735928495 +# CHECK-NEXT: .8byte -47981953555775825 +# CHECK-NEXT: .8byte -2401053363754123601 +# CHECK-NEXT: .byte 255 +# CHECK-NEXT: .byte 85 +# CHECK-NEXT: .byte 136 +# CHECK-NEXT: .2byte 65365 +# CHECK-NEXT: .2byte 34986 +# CHECK-NEXT: .4byte 4283795626 +# CHECK-NEXT: .4byte 3735928495 +# CHECK-NEXT: .4byte 4283795626 +# CHECK-NEXT: .4byte 3735928495 +# CHECK-NEXT: .8byte -47981953555775825 +# CHECK-NEXT: .8byte -2401053363754123601 +# CHECK-NEXT: .8byte -47981953555775825 +# CHECK-NEXT: .8byte -2401053363754123601 +# CHECK-NEXT: .8byte -47981953555775825 +# CHECK-NEXT: .8byte -2401053363754123601 + +# OBJ: Contents of section .data: +# OBJ-NEXT: 0000 55ffaa88 aa8855ff afbeadde afbeadde +# OBJ-NEXT: 0010 aa8855ff afbeadde afbeadde ff558855 +# OBJ-NEXT: 0020 ffaa88aa 8855ffaf beaddeaa 8855ffaf +# OBJ-NEXT: 0030 beaddeaf beaddeaa 8855ffaf beaddeaf +# OBJ-NEXT: 0040 beaddeaf beaddeaa 8855ffaf beaddeaf +# OBJ-NEXT: 0050 beaddeaf beaddeaa 8855ffaf beaddeaf +# OBJ-NEXT: 0060 beadde -- 2.7.4