[PATCH 1/2] x86: PadLock adjustments

Jan Beulich jbeulich@suse.com
Fri Sep 26 12:57:03 GMT 2025


For one, all PadLock insns depend on CR4.FXSR to be enabled, which means
they ought to be taking FXSR as a prereq.

Furthermore none of them permits a REPNE prefix; such forms are documented
to cause #UD. (This is mainly relevant for XSTORE, which doesn't include a
REP prefix in its base encoding. For the others this merely is a change in
what diagnostic is issued.)

Finally it is documented that an operand size prefix also causes #UD.
---
Question is whether for the GMI insns the data size prefix is invalid as
well.

--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -4899,11 +4899,6 @@ check_hle (void)
   switch (i.tm.opcode_modifier.prefixok)
     {
     default:
-      abort ();
-    case PrefixLock:
-    case PrefixNone:
-    case PrefixNoTrack:
-    case PrefixRep:
       as_bad (_("invalid instruction `%s' after `%s'"),
 	      insn_name (&i.tm), i.hle_prefix);
       return 0;
@@ -7372,7 +7367,9 @@ i386_assemble (char *line)
       return;
 
   /* Check if REP prefix is OK.  */
-  if (i.rep_prefix && i.tm.opcode_modifier.prefixok != PrefixRep)
+  if (i.rep_prefix && i.tm.opcode_modifier.prefixok != PrefixRep
+      && (i.prefix[REP_PREFIX] != REPE_PREFIX_OPCODE
+	  || i.tm.opcode_modifier.prefixok != PrefixRepe))
     {
       as_bad (_("invalid instruction `%s' after `%s'"),
 		insn_name (&i.tm), i.rep_prefix);
@@ -7416,9 +7413,13 @@ i386_assemble (char *line)
 
   if ((is_any_vex_encoding (&i.tm) && i.tm.opcode_space != SPACE_MAP4)
       || i.tm.operand_types[i.imm_operands].bitfield.class >= RegMMX
-      || i.tm.operand_types[i.imm_operands + 1].bitfield.class >= RegMMX)
+      || i.tm.operand_types[i.imm_operands + 1].bitfield.class >= RegMMX
+      /* (Ab)use the PrefixRepe attribute of PadLock insns as long as no
+	 others use it.  */
+      || i.tm.opcode_modifier.prefixok == PrefixRepe)
     {
-      /* Check for data size prefix on VEX/XOP/EVEX encoded and SIMD insns.  */
+      /* Check for data size prefix on VEX/XOP/EVEX encoded, SIMD, and
+	 PadLock insns.  */
       if (i.prefix[DATA_PREFIX])
 	{
 	  as_bad (_("data size prefix invalid with `%s'"), insn_name (&i.tm));
--- a/gas/testsuite/gas/i386/i386.exp
+++ b/gas/testsuite/gas/i386/i386.exp
@@ -114,6 +114,7 @@ if [gas_32_check] then {
     run_dump_test "quoted2"
     run_dump_test "unary"
     run_dump_test "padlock"
+    run_list_test "padlock-bad"
     run_dump_test "gmi"
     run_dump_test "padlockrng2"
     run_dump_test "padlockphe2"
--- /dev/null
+++ b/gas/testsuite/gas/i386/padlock-bad.l
@@ -0,0 +1,5 @@
+.* Assembler messages:
+.*:8: Error: invalid instruction `xstore' after `repne'
+.*:10: Error: data size prefix invalid with `xstore'
+.*:15: Error: invalid instruction `xsha1' after `repne'
+.*:17: Error: data size prefix invalid with `xsha1'
--- /dev/null
+++ b/gas/testsuite/gas/i386/padlock-bad.s
@@ -0,0 +1,17 @@
+# VIA Nehemiah PadLock instructions w/ (problematic) prefixes
+
+	.text
+foo:
+	xstore
+	rep xstore
+	repe xstore
+	repne xstore
+
+	data16 xstore
+
+	xsha1
+	rep xsha1
+	repe xsha1
+	repne xsha1
+
+	data16 xsha1
--- a/opcodes/i386-gen.c
+++ b/opcodes/i386-gen.c
@@ -297,6 +297,8 @@ static const dependency isa_dependencies
     "64" },
   { "APX_F",
     "XSAVE|64" },
+  { "PadLock",
+    "FXSR" },
   { "PadLockRNG2",
     "PadLock" },
   { "PadLockPHE2",
--- a/opcodes/i386-opc.h
+++ b/opcodes/i386-opc.h
@@ -663,13 +663,14 @@ enum
   BNDPrefixOk,
 #define PrefixNone		0
 #define PrefixRep		1
-#define PrefixHLERelease	2 /* Okay with an XRELEASE (0xf3) prefix. */
-#define PrefixNoTrack		3
+#define PrefixRepe		2
+#define PrefixHLERelease	3 /* Okay with an XRELEASE (0xf3) prefix. */
+#define PrefixNoTrack		4
   /* Prefixes implying "LOCK okay" must come after Lock. All others have
      to come before.  */
-#define PrefixLock		4
-#define PrefixHLELock		5 /* Okay with a LOCK prefix.  */
-#define PrefixHLEAny		6 /* Okay with or without a LOCK prefix.  */
+#define PrefixLock		5
+#define PrefixHLELock		6 /* Okay with a LOCK prefix.  */
+#define PrefixHLEAny		7 /* Okay with or without a LOCK prefix.  */
   PrefixOk,
   /* opcode is a prefix */
   IsPrefix,
--- a/opcodes/i386-opc.tbl
+++ b/opcodes/i386-opc.tbl
@@ -103,6 +103,7 @@
 #define IsStringEsOp1 IsString=IS_STRING_ES_OP1
 
 #define RepPrefixOk      PrefixOk=PrefixRep
+#define RepePrefixOk     PrefixOk=PrefixRepe
 #define LockPrefixOk     PrefixOk=PrefixLock
 #define HLEPrefixAny     PrefixOk=PrefixHLEAny
 #define HLEPrefixLock    PrefixOk=PrefixHLELock
@@ -2122,24 +2123,24 @@ popcnt, 0xf30fb8, POPCNT, Modrm|CheckOpe
 popcnt, 0x88, POPCNT&APX_F, Modrm|CheckOperandSize|No_bSuf|No_sSuf|EVexMap4|NF, { Reg16|Reg32|Reg64|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
 
 // VIA PadLock extensions.
-xstore-rng, 0xfa7c0, PadLock, NoSuf|RepPrefixOk, {}
-xcrypt-ecb, 0xf30fa7c8, PadLock, NoSuf|RepPrefixOk, {}
-xcrypt-cbc, 0xf30fa7d0, PadLock, NoSuf|RepPrefixOk, {}
-xcrypt-ctr, 0xf30fa7d8, PadLock, NoSuf|RepPrefixOk, {}
-xcrypt-cfb, 0xf30fa7e0, PadLock, NoSuf|RepPrefixOk, {}
-xcrypt-ofb, 0xf30fa7e8, PadLock, NoSuf|RepPrefixOk, {}
-montmul, 0xf30fa6c0, PadLock, NoSuf|RepPrefixOk, {}
-xsha1, 0xf30fa6c8, PadLock, NoSuf|RepPrefixOk, {}
-xsha256, 0xf30fa6d0, PadLock, NoSuf|RepPrefixOk, {}
+xstore-rng, 0xfa7c0, PadLock, NoSuf|RepePrefixOk, {}
+xcrypt-ecb, 0xf30fa7c8, PadLock, NoSuf|RepePrefixOk, {}
+xcrypt-cbc, 0xf30fa7d0, PadLock, NoSuf|RepePrefixOk, {}
+xcrypt-ctr, 0xf30fa7d8, PadLock, NoSuf|RepePrefixOk, {}
+xcrypt-cfb, 0xf30fa7e0, PadLock, NoSuf|RepePrefixOk, {}
+xcrypt-ofb, 0xf30fa7e8, PadLock, NoSuf|RepePrefixOk, {}
+montmul, 0xf30fa6c0, PadLock, NoSuf|RepePrefixOk, {}
+xsha1, 0xf30fa6c8, PadLock, NoSuf|RepePrefixOk, {}
+xsha256, 0xf30fa6d0, PadLock, NoSuf|RepePrefixOk, {}
 // Aliases without hyphens.
-xstorerng, 0xfa7c0, PadLock, NoSuf|RepPrefixOk, {}
-xcryptecb, 0xf30fa7c8, PadLock, NoSuf|RepPrefixOk, {}
-xcryptcbc, 0xf30fa7d0, PadLock, NoSuf|RepPrefixOk, {}
-xcryptctr, 0xf30fa7d8, PadLock, NoSuf|RepPrefixOk, {}
-xcryptcfb, 0xf30fa7e0, PadLock, NoSuf|RepPrefixOk, {}
-xcryptofb, 0xf30fa7e8, PadLock, NoSuf|RepPrefixOk, {}
+xstorerng, 0xfa7c0, PadLock, NoSuf|RepePrefixOk, {}
+xcryptecb, 0xf30fa7c8, PadLock, NoSuf|RepePrefixOk, {}
+xcryptcbc, 0xf30fa7d0, PadLock, NoSuf|RepePrefixOk, {}
+xcryptctr, 0xf30fa7d8, PadLock, NoSuf|RepePrefixOk, {}
+xcryptcfb, 0xf30fa7e0, PadLock, NoSuf|RepePrefixOk, {}
+xcryptofb, 0xf30fa7e8, PadLock, NoSuf|RepePrefixOk, {}
 // Alias for xstore-rng.
-xstore, 0xfa7c0, PadLock, NoSuf|RepPrefixOk, {}
+xstore, 0xfa7c0, PadLock, NoSuf|RepePrefixOk, {}
 
 // Zhaoxin GMI SM2 instruction
 sm2, 0xf20fa6c0, GMISM2, NoSuf, {}
@@ -2149,15 +2150,15 @@ sm3, 0xf30fa6e8, GMICCS, NoSuf, {}
 sm4, 0xf30fa7f0, GMICCS, NoSuf, {}
 
 // Zhaoxin PadLock RNG2 instruction
-xrng2, 0xf30fa7f8, PadLockRNG2, NoSuf|RepPrefixOk, {}
+xrng2, 0xf30fa7f8, PadLockRNG2, NoSuf|RepePrefixOk, {}
 
 // Zhaoxin PadLock PHE2 instructions
-xsha384, 0xf30fa6d8, PadLockPHE2, NoSuf|RepPrefixOk, {}
-xsha512, 0xf30fa6e0, PadLockPHE2, NoSuf|RepPrefixOk, {}
+xsha384, 0xf30fa6d8, PadLockPHE2, NoSuf|RepePrefixOk, {}
+xsha512, 0xf30fa6e0, PadLockPHE2, NoSuf|RepePrefixOk, {}
 
 // Zhaoxin PadLock XMODX instructions
-montmul2, 0xf30fa6f0, PadLockXMODX, NoSuf|RepPrefixOk, {}
-xmodexp, 0xf30fa6f8, PadLockXMODX, NoSuf|RepPrefixOk, {}
+montmul2, 0xf30fa6f0, PadLockXMODX, NoSuf|RepePrefixOk, {}
+xmodexp, 0xf30fa6f8, PadLockXMODX, NoSuf|RepePrefixOk, {}
 
 // Multy-precision Add Carry, rdseed instructions.
 <adx:pfx, c:66, o:f3>



More information about the Binutils mailing list