[VE] Support VE specific data directives in MC
authorKazushi (Jam) Marukawa <marukawa@nec.com>
Sun, 5 Dec 2021 18:52:26 +0000 (03:52 +0900)
committerKazushi (Jam) Marukawa <marukawa@nec.com>
Mon, 6 Dec 2021 11:07:44 +0000 (20:07 +0900)
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
llvm/test/MC/VE/data-size-error.s [new file with mode: 0644]
llvm/test/MC/VE/data.s [new file with mode: 0644]

index 7e92e4b..fd9dc32 100644 (file)
@@ -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 (file)
index 0000000..0313944
--- /dev/null
@@ -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 (file)
index 0000000..f0ff830
--- /dev/null
@@ -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