public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
From: Claudio Bantaloukas <claudio.bantaloukas@arm.com>
To: <binutils@sourceware.org>
Cc: Claudio Bantaloukas <claudio.bantaloukas@arm.com>
Subject: [PATCH 1/2] aarch64: add Branch Record Buffer extension instructions
Date: Fri, 7 Jun 2024 13:59:02 +0000	[thread overview]
Message-ID: <20240607135903.14295-2-claudio.bantaloukas@arm.com> (raw)
In-Reply-To: <20240607135903.14295-1-claudio.bantaloukas@arm.com>

[-- Attachment #1: Type: text/plain, Size: 2628 bytes --]


The FEAT_BRBE extension provides two aliases of sys:
- brb iall (Invalidates all Branch records in the Branch Record Buffer)
- brb inj (Injects the Branch Record held in BRBINFINJ_EL1,
  BRBSRCINJ_EL1, and BRBTGTINJ_EL1 into the Branch Record Buffer)

This patch adds:
- the feature option "brbe" that must be added for the aliases to be available
- a new operand flag AARCH64_OPND_Rt_IN_SYS_ALIASES that warns in a comment
  when Rt is set to the non default value 0b11111 (it is constrained
  unpredictable whether the instruction is undefined or behaves as if the Rt
  field is set to 0b11111).
- a new operand flag AARCH64_OPND_BRBOP that encodes and decodes Op2 values
  from bit 5
- support for the two brb aliases above

See:
- https://developer.arm.com/documentation/ddi0602/2024-03/Base-Instructions/BRB--Branch-Record-Buffer--an-alias-of-SYS-?lang=en
- https://developer.arm.com/documentation/ddi0601/2024-03/AArch64-Instructions/BRB-INJ--Branch-Record-Injection-into-the-Branch-Record-Buffer?lang=en
- https://developer.arm.com/documentation/ddi0601/2024-03/AArch64-Instructions/BRB-IALL--Invalidate-the-Branch-Record-Buffer?lang=en
---
 gas/config/tc-aarch64.c                      |  8 +++++++
 gas/doc/c-aarch64.texi                       |  2 ++
 gas/testsuite/gas/aarch64/brbe-brb-bad.d     |  2 ++
 gas/testsuite/gas/aarch64/brbe-brb-bad.l     |  4 ++++
 gas/testsuite/gas/aarch64/brbe-brb-bad.s     |  6 +++++
 gas/testsuite/gas/aarch64/brbe-brb-inst.d    | 14 ++++++++++++
 gas/testsuite/gas/aarch64/brbe-brb-inst.s    |  5 ++++
 gas/testsuite/gas/aarch64/brbe-brb-invalid.d |  3 +++
 gas/testsuite/gas/aarch64/brbe-brb-invalid.l |  3 +++
 gas/testsuite/gas/aarch64/brbe-brb.d         | 12 ++++++++++
 gas/testsuite/gas/aarch64/brbe-brb.s         |  5 ++++
 include/opcode/aarch64.h                     |  7 +++++-
 opcodes/aarch64-opc.c                        | 24 ++++++++++++++++++++
 opcodes/aarch64-opc.h                        |  1 +
 opcodes/aarch64-tbl.h                        | 15 ++++++++++++
 15 files changed, 110 insertions(+), 1 deletion(-)
 create mode 100644 gas/testsuite/gas/aarch64/brbe-brb-bad.d
 create mode 100644 gas/testsuite/gas/aarch64/brbe-brb-bad.l
 create mode 100644 gas/testsuite/gas/aarch64/brbe-brb-bad.s
 create mode 100644 gas/testsuite/gas/aarch64/brbe-brb-inst.d
 create mode 100644 gas/testsuite/gas/aarch64/brbe-brb-inst.s
 create mode 100644 gas/testsuite/gas/aarch64/brbe-brb-invalid.d
 create mode 100644 gas/testsuite/gas/aarch64/brbe-brb-invalid.l
 create mode 100644 gas/testsuite/gas/aarch64/brbe-brb.d
 create mode 100644 gas/testsuite/gas/aarch64/brbe-brb.s


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-aarch64-add-Branch-Record-Buffer-extension-instructi.patch --]
[-- Type: text/x-patch; name="0001-aarch64-add-Branch-Record-Buffer-extension-instructi.patch", Size: 12845 bytes --]

diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index fec17c40a43..0beb2c875d8 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -6235,6 +6235,7 @@ process_omitted_operand (enum aarch64_opnd type, const aarch64_opcode *opcode,
     case AARCH64_OPND_Rs:
     case AARCH64_OPND_Ra:
     case AARCH64_OPND_Rt_SYS:
+    case AARCH64_OPND_Rt_IN_SYS_ALIASES:
     case AARCH64_OPND_Rd_SP:
     case AARCH64_OPND_Rn_SP:
     case AARCH64_OPND_Rm_SP:
@@ -6619,6 +6620,7 @@ parse_operands (char *str, const aarch64_opcode *opcode)
 	case AARCH64_OPND_Ra:
 	case AARCH64_OPND_Rt_LS64:
 	case AARCH64_OPND_Rt_SYS:
+	case AARCH64_OPND_Rt_IN_SYS_ALIASES:
 	case AARCH64_OPND_PAIRREG:
 	case AARCH64_OPND_PAIRREG_OR_XZR:
 	case AARCH64_OPND_SVE_Rm:
@@ -8076,6 +8078,11 @@ parse_operands (char *str, const aarch64_opcode *opcode)
 	  info->imm.value = val;
 	  break;
 
+	case AARCH64_OPND_BRBOP:
+	  po_strict_enum_or_fail (aarch64_brbop_array);
+	  info->imm.value = val;
+	  break;
+
 	case AARCH64_OPND_MOPS_ADDR_Rd:
 	case AARCH64_OPND_MOPS_ADDR_Rs:
 	  po_char_or_fail ('[');
@@ -10551,6 +10558,7 @@ static const struct aarch64_option_cpu_value_table aarch64_features[] = {
   {"faminmax",		AARCH64_FEATURE (FAMINMAX), AARCH64_FEATURE (SIMD)},
   {"fp8",		AARCH64_FEATURE (FP8), AARCH64_FEATURE (SIMD)},
   {"lut",		AARCH64_FEATURE (LUT), AARCH64_FEATURE (SIMD)},
+  {"brbe",		AARCH64_FEATURE (BRBE), AARCH64_NO_FEATURES},
   {NULL,		AARCH64_NO_FEATURES, AARCH64_NO_FEATURES},
 };
 
diff --git a/gas/doc/c-aarch64.texi b/gas/doc/c-aarch64.texi
index b622f30b146..b29da1f0e8f 100644
--- a/gas/doc/c-aarch64.texi
+++ b/gas/doc/c-aarch64.texi
@@ -165,6 +165,8 @@ automatically cause those extensions to be disabled.
  @tab Enable BFloat16 to BFloat16 arithmetic for SVE2 and SME2.
 @item @code{bf16} @tab @code{fp}
  @tab Enable BFloat16 extension.
+@item @code{brbe} @tab
+ @tab Enable the Branch Record Buffer extension.
 @item @code{chk} @tab
  @tab Enable the Check Feature Status Extension.
 @item @code{compnum} @tab @code{simd}
diff --git a/gas/testsuite/gas/aarch64/brbe-brb-bad.d b/gas/testsuite/gas/aarch64/brbe-brb-bad.d
new file mode 100644
index 00000000000..6afe74d6a1a
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/brbe-brb-bad.d
@@ -0,0 +1,2 @@
+#as: -march=armv9.1-a+brbe
+#error_output: brbe-brb-bad.l
diff --git a/gas/testsuite/gas/aarch64/brbe-brb-bad.l b/gas/testsuite/gas/aarch64/brbe-brb-bad.l
new file mode 100644
index 00000000000..b220d9a9c8d
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/brbe-brb-bad.l
@@ -0,0 +1,4 @@
+.*: Assembler messages:
+.*: Error: operand 1 must be Branch Record Buffer operation operand -- `brb foobar'
+.*: Error: operand 1 must be Branch Record Buffer operation operand -- `brb #123'
+.*: Error: operand 1 must be Branch Record Buffer operation operand -- `brb'
diff --git a/gas/testsuite/gas/aarch64/brbe-brb-bad.s b/gas/testsuite/gas/aarch64/brbe-brb-bad.s
new file mode 100644
index 00000000000..862290f1f56
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/brbe-brb-bad.s
@@ -0,0 +1,6 @@
+/* brb only accepts iall and inj as arguments */
+.text
+
+brb foobar
+brb #123
+brb
diff --git a/gas/testsuite/gas/aarch64/brbe-brb-inst.d b/gas/testsuite/gas/aarch64/brbe-brb-inst.d
new file mode 100644
index 00000000000..748d36c38a9
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/brbe-brb-inst.d
@@ -0,0 +1,14 @@
+#as: -march=armv9.1-a+brbe
+#objdump: -dr
+# This test is only valid on ELF based ports.
+#notarget: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd
+
+.*:     file format .*
+
+Disassembly of section \.text:
+
+0+ <.*>:
+.*:	d509729f 	brb	iall
+.*:	d509729e 	brb	iall	// unpredictable encoding \(Rt!=31\): #30
+.*:	d50972bf 	brb	inj
+.*:	d50972be 	brb	inj	// unpredictable encoding \(Rt!=31\): #30
diff --git a/gas/testsuite/gas/aarch64/brbe-brb-inst.s b/gas/testsuite/gas/aarch64/brbe-brb-inst.s
new file mode 100644
index 00000000000..e05a8808ad1
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/brbe-brb-inst.s
@@ -0,0 +1,5 @@
+	.text
+	.inst 0xd509729f // brb iall
+	.inst 0xd509729e // brb iall with non default Rt
+	.inst 0xd50972bf // brb inj
+	.inst 0xd50972be // brb inj with non default Rt
diff --git a/gas/testsuite/gas/aarch64/brbe-brb-invalid.d b/gas/testsuite/gas/aarch64/brbe-brb-invalid.d
new file mode 100644
index 00000000000..fbd2608696b
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/brbe-brb-invalid.d
@@ -0,0 +1,3 @@
+#as: -march=armv9.1-a
+#source: brbe-brb.s
+#error_output: brbe-brb-invalid.l
diff --git a/gas/testsuite/gas/aarch64/brbe-brb-invalid.l b/gas/testsuite/gas/aarch64/brbe-brb-invalid.l
new file mode 100644
index 00000000000..98e164acab4
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/brbe-brb-invalid.l
@@ -0,0 +1,3 @@
+.*: Assembler messages:
+.*: Error: selected processor does not support `brb iall'
+.*: Error: selected processor does not support `brb inj'
diff --git a/gas/testsuite/gas/aarch64/brbe-brb.d b/gas/testsuite/gas/aarch64/brbe-brb.d
new file mode 100644
index 00000000000..0ab23849614
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/brbe-brb.d
@@ -0,0 +1,12 @@
+#as: -march=armv9.1-a+brbe
+#objdump: -dr
+
+.*:     file format .*
+
+Disassembly of section \.text:
+
+0+ <.*>:
+.*:	d509729f 	brb	iall
+.*:	d509729f 	brb	iall
+.*:	d50972bf 	brb	inj
+.*:	d50972bf 	brb	inj
diff --git a/gas/testsuite/gas/aarch64/brbe-brb.s b/gas/testsuite/gas/aarch64/brbe-brb.s
new file mode 100644
index 00000000000..01b684e42e3
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/brbe-brb.s
@@ -0,0 +1,5 @@
+	.text
+	brb	iall
+	.inst	0xd509729f // brb iall
+	brb	inj
+	.inst	0xd50972bf // brb inj
diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h
index 8a21611e3ff..c83c0a4ebb4 100644
--- a/include/opcode/aarch64.h
+++ b/include/opcode/aarch64.h
@@ -238,6 +238,8 @@ enum aarch64_feature_bit {
   AARCH64_FEATURE_FP8,
   /* LUT instructions.  */
   AARCH64_FEATURE_LUT,
+  /* Branch Record Buffer Extension */
+  AARCH64_FEATURE_BRBE,
   AARCH64_NUM_FEATURES
 };
 
@@ -625,6 +627,8 @@ enum aarch64_opnd
   AARCH64_OPND_BARRIER_PSB,	/* Barrier operand for PSB.  */
   AARCH64_OPND_BARRIER_GCSB,	/* Barrier operand for GCSB.  */
   AARCH64_OPND_BTI_TARGET,	/* BTI {<target>}.  */
+  AARCH64_OPND_BRBOP,		/* BRB operation IALL or INJ in bit 5.  */
+  AARCH64_OPND_Rt_IN_SYS_ALIASES,	/* Defaulted and omitted Rt used in SYS aliases such as brb.  */
   AARCH64_OPND_LSE128_Rt,	/* LSE128 <Xt1>.  */
   AARCH64_OPND_LSE128_Rt2,	/* LSE128 <Xt2>.  */
   AARCH64_OPND_SVE_ADDR_RI_S4x16,   /* SVE [<Xn|SP>, #<simm4>*16].  */
@@ -822,7 +826,7 @@ enum aarch64_opnd
   AARCH64_OPND_RCPC3_ADDR_OPT_PREIND_WB, /* [<Xn|SP>] or [<Xn|SP>, #<imm>]!.  */
   AARCH64_OPND_RCPC3_ADDR_POSTIND,	 /* [<Xn|SP>], #<imm>.  */
   AARCH64_OPND_RCPC3_ADDR_PREIND_WB, 	 /* [<Xn|SP>, #<imm>]!.  */
-  AARCH64_OPND_RCPC3_ADDR_OFFSET
+  AARCH64_OPND_RCPC3_ADDR_OFFSET,
 };
 
 /* Qualifier constrains an operand.  It either specifies a variant of an
@@ -1918,6 +1922,7 @@ extern const char *const aarch64_sve_pattern_array[32];
 extern const char *const aarch64_sve_prfop_array[16];
 extern const char *const aarch64_rprfmop_array[64];
 extern const char *const aarch64_sme_vlxn_array[2];
+extern const char *const aarch64_brbop_array[2];
 
 #ifdef __cplusplus
 }
diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c
index bbe6f09808b..ea278bfdfe5 100644
--- a/opcodes/aarch64-opc.c
+++ b/opcodes/aarch64-opc.c
@@ -117,6 +117,12 @@ const char *const aarch64_sme_vlxn_array[2] = {
   "vlx4"
 };
 
+/* Values accepted by the brb alias.  */
+const char *const aarch64_brbop_array[] = {
+  "iall",
+  "inj",
+};
+
 /* Helper functions to determine which operand to be used to encode/decode
    the size:Q fields for AdvSIMD instructions.  */
 
@@ -418,6 +424,7 @@ const aarch64_field fields[] =
     {  6,  1 }, /* ZAn: name of the bit encoded ZA tile.  */
     { 12,  4 },	/* opc2: in rcpc3 ld/st inst deciding the pre/post-index.  */
     { 30,  2 },	/* rcpc3_size: in rcpc3 ld/st, field controls Rt/Rt2 width.  */
+    { 5,  1 },	/* FLD_brbop: used in BRB to mean IALL or INJ.  */
 };
 
 enum aarch64_operand_class
@@ -3958,6 +3965,7 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
     case AARCH64_OPND_Rt2:
     case AARCH64_OPND_Rs:
     case AARCH64_OPND_Ra:
+    case AARCH64_OPND_Rt_IN_SYS_ALIASES:
     case AARCH64_OPND_Rt_LS64:
     case AARCH64_OPND_Rt_SYS:
     case AARCH64_OPND_PAIRREG:
@@ -3973,6 +3981,15 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
 	  if (!opnd->present)
 	    break;
 	}
+      else if ((opnd->type == AARCH64_OPND_Rt_IN_SYS_ALIASES)
+	       && (opnd->reg.regno
+		   != get_optional_operand_default_value (opcode)))
+	{
+	  /* Avoid printing an invalid additional value for Rt in SYS aliases such as
+	     BRB, provide a helpful comment instead */
+	  snprintf (comment, comment_size, "unpredictable encoding (Rt!=31): #%" PRIi64, opnd->imm.value);
+	  break;
+	}
       /* Omit the operand, e.g. RET.  */
       else if (optional_operand_p (opcode, idx)
 	       && (opnd->reg.regno
@@ -4355,6 +4372,13 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
 		style_sub_mnem (styler, aarch64_sme_vlxn_array[enum_value]));
       break;
 
+    case AARCH64_OPND_BRBOP:
+      enum_value = opnd->imm.value;
+      assert (enum_value < ARRAY_SIZE (aarch64_brbop_array));
+      snprintf (buf, size, "%s",
+		style_sub_mnem (styler, aarch64_brbop_array[enum_value]));
+      break;
+
     case AARCH64_OPND_CRn:
     case AARCH64_OPND_CRm:
       snprintf (buf, size, "%s",
diff --git a/opcodes/aarch64-opc.h b/opcodes/aarch64-opc.h
index 8bf3fc8b874..9b734d63a3b 100644
--- a/opcodes/aarch64-opc.h
+++ b/opcodes/aarch64-opc.h
@@ -225,6 +225,7 @@ enum aarch64_field_kind
   FLD_ZAn,
   FLD_opc2,
   FLD_rcpc3_size,
+  FLD_brbop,
 };
 
 /* Field description.  */
diff --git a/opcodes/aarch64-tbl.h b/opcodes/aarch64-tbl.h
index 1d12630273e..bffb422583a 100644
--- a/opcodes/aarch64-tbl.h
+++ b/opcodes/aarch64-tbl.h
@@ -100,6 +100,11 @@
   QLF1(NIL),			\
 }
 
+#define QL_IMM_NIL_NIL		\
+{				\
+  QLF2(NIL, NIL),		\
+}
+
 /* e.g. B.<cond> <label>.  */
 #define QL_PCREL_NIL		\
 {				\
@@ -2745,6 +2750,8 @@ static const aarch64_feature_set aarch64_feature_lut =
   AARCH64_FEATURE (LUT);
 static const aarch64_feature_set aarch64_feature_lut_sve2 =
   AARCH64_FEATURES (2, LUT, SVE2);
+static const aarch64_feature_set aarch64_feature_brbe =
+  AARCH64_FEATURE (BRBE);
 
 #define CORE		&aarch64_feature_v8
 #define FP		&aarch64_feature_fp
@@ -2821,6 +2828,7 @@ static const aarch64_feature_set aarch64_feature_lut_sve2 =
 #define FP8_SME2   &aarch64_feature_fp8_sme2
 #define LUT &aarch64_feature_lut
 #define LUT_SVE2 &aarch64_feature_lut_sve2
+#define BRBE		&aarch64_feature_brbe
 
 #define CORE_INSN(NAME,OPCODE,MASK,CLASS,OP,OPS,QUALS,FLAGS) \
   { NAME, OPCODE, MASK, CLASS, OP, CORE, OPS, QUALS, FLAGS, 0, 0, NULL }
@@ -3019,6 +3027,8 @@ static const aarch64_feature_set aarch64_feature_lut_sve2 =
 #define LUT_SVE2_INSN(NAME,OPCODE,MASK,OPS,QUALS,FLAGS,CONSTRAINTS) \
   { NAME, OPCODE, MASK, lut, 0, LUT_SVE2, OPS, QUALS, \
     FLAGS, CONSTRAINTS, 0, NULL }
+#define BRBE_INSN(NAME,OPCODE,MASK,OPS,QUALS,FLAGS) \
+  { NAME, OPCODE, MASK, ic_system, 0, BRBE, OPS, QUALS, FLAGS, 0, 0, NULL }
 
 #define MOPS_CPY_OP1_OP2_PME_INSN(NAME, OPCODE, MASK, FLAGS, CONSTRAINTS) \
   MOPS_INSN (NAME, OPCODE, MASK, 0, \
@@ -4443,6 +4453,7 @@ const struct aarch64_opcode aarch64_opcode_table[] =
   PREDRES_INSN ("dvp", 0xd50b73a0, 0xffffffe0, ic_system, OP2 (SYSREG_SR, Rt), QL_SRC_X, F_ALIAS),
   PREDRES_INSN ("cpp", 0xd50b73e0, 0xffffffe0, ic_system, OP2 (SYSREG_SR, Rt), QL_SRC_X, F_ALIAS),
   PREDRES2_INSN ("cosp", 0xd50b73c0, 0xffffffe0, ic_system, OP2 (SYSREG_SR, Rt), QL_SRC_X, F_ALIAS),
+  BRBE_INSN ("brb", 0xd5097280, 0xffffffc0, OP2 (BRBOP, Rt_IN_SYS_ALIASES), QL_IMM_NIL_NIL, F_ALIAS | F_OPD1_OPT | F_DEFAULT (0x1F)),
   /* Armv8.4-a flag setting instruction, However this encoding has an encoding clash with the msr
      below it.  Usually we can resolve this by setting an alias condition on the flags, however that
      depends on the disassembly masks to be able to quickly find the alias.  The problem is the
@@ -6836,6 +6847,10 @@ const struct aarch64_opcode aarch64_opcode_table[] =
       "the GCSB option name DSYNC")					\
     Y(SYSTEM, hint, "BTI_TARGET", 0, F (),				\
       "BTI targets j/c/jc")						\
+    Y(SYSTEM, imm, "BRBOP", 0, F(FLD_brbop),				\
+      "Branch Record Buffer operation operand")				\
+    Y(INT_REG, regno, "Rt_IN_SYS_ALIASES", 0, F(FLD_Rt),		\
+      "Rt register with defaults for SYS aliases")			\
     Y(INT_REG, regno, "LSE128_Rt", 0, F(FLD_LSE128_Rt), "an integer register") \
     Y(INT_REG, regno, "LSE128_Rt2", 0, F(FLD_LSE128_Rt2), "an integer register") \
     Y(ADDRESS, sve_addr_ri_s4, "SVE_ADDR_RI_S4x16",			\

  reply	other threads:[~2024-06-07 13:59 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-06-07 13:59 [PATCH 0/2] " Claudio Bantaloukas
2024-06-07 13:59 ` Claudio Bantaloukas [this message]
2024-06-10  6:58   ` [PATCH 1/2] " Jan Beulich
2024-06-10 11:00     ` Claudio Bantaloukas
2024-06-25 17:00       ` Richard Earnshaw (lists)
2024-06-12 13:52     ` Richard Earnshaw (lists)
2024-06-07 13:59 ` [PATCH 2/2] " Claudio Bantaloukas
2024-06-12 13:59 ` [PATCH 0/2] " Richard Earnshaw (lists)

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240607135903.14295-2-claudio.bantaloukas@arm.com \
    --to=claudio.bantaloukas@arm.com \
    --cc=binutils@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).