* [PATCH] MIPS: R6: load/store can process unaligned address
@ 2021-02-28 7:16 YunQiang Su
2021-03-12 10:30 ` YunQiang Su
0 siblings, 1 reply; 3+ messages in thread
From: YunQiang Su @ 2021-02-28 7:16 UTC (permalink / raw)
To: gcc-patches; +Cc: macro, law, doko, syq, jiaxun.yang, YunQiang Su
MIPS release 6 requires the lw/ld/sw/sd can work with
unaligned address, while it can be implemented by
full hardware or trap&emulate.
Since it is may be fully done by hardware, we add an
option -m(no-)unaligned-access, the kernel may need it.
gcc/ChangeLog:
* config/mips/mips.h (ISA_HAS_UNALIGNED_ACCESS):
(STRICT_ALIGNMENT): R6 can unaligned access.
* config/mips/mips.md (movmisalign<mode>): Likewise.
* config/mips/mips.opt: add -m(no-)unaligned-access
* doc/invoke.texi: Likewise.
gcc/testsuite/ChangeLog:
* gcc.target/mips/mips.exp: add unaligned-access
* gcc.target/mips/unaligned-2.c: New test.
* gcc.target/mips/unaligned-3.c: New test.
---
gcc/config/mips/mips.h | 6 ++-
gcc/config/mips/mips.md | 10 ++++
gcc/config/mips/mips.opt | 4 ++
gcc/doc/invoke.texi | 10 ++++
gcc/testsuite/gcc.target/mips/mips.exp | 1 +
gcc/testsuite/gcc.target/mips/unaligned-2.c | 53 +++++++++++++++++++++
gcc/testsuite/gcc.target/mips/unaligned-3.c | 53 +++++++++++++++++++++
7 files changed, 136 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/gcc.target/mips/unaligned-2.c
create mode 100644 gcc/testsuite/gcc.target/mips/unaligned-3.c
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index b4a60a55d80..38c39f79ee2 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -226,6 +226,10 @@ struct mips_cpu_info {
&& (mips_isa_rev >= 6 \
|| ISA_HAS_MSA))
+/* ISA load/store instructions can handle unaligned address */
+#define ISA_HAS_UNALIGNED_ACCESS (TARGET_UNALIGNED_ACCESS \
+ && (mips_isa_rev >= 6))
+
/* The ISA compression flags that are currently in effect. */
#define TARGET_COMPRESSION (target_flags & (MASK_MIPS16 | MASK_MICROMIPS))
@@ -1665,7 +1669,7 @@ FP_ASM_SPEC "\
(ISA_HAS_MSA ? BITS_PER_MSA_REG : LONG_DOUBLE_TYPE_SIZE)
/* All accesses must be aligned. */
-#define STRICT_ALIGNMENT 1
+#define STRICT_ALIGNMENT (!ISA_HAS_UNALIGNED_ACCESS)
/* Define this if you wish to imitate the way many other C compilers
handle alignment of bitfields and the structures that contain
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index eef3cfd50a8..40e29c60432 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -4459,6 +4459,16 @@ (define_insn "mov_<store>r"
[(set_attr "move_type" "store")
(set_attr "mode" "<MODE>")])
+;; Unaligned direct access
+(define_expand "movmisalign<mode>"
+ [(set (match_operand:JOIN_MODE 0)
+ (match_operand:JOIN_MODE 1))]
+ "ISA_HAS_UNALIGNED_ACCESS"
+{
+ if (mips_legitimize_move (<MODE>mode, operands[0], operands[1]))
+ DONE;
+})
+
;; An instruction to calculate the high part of a 64-bit SYMBOL_ABSOLUTE.
;; The required value is:
;;
diff --git a/gcc/config/mips/mips.opt b/gcc/config/mips/mips.opt
index 6af8037e9bd..ebb4c616401 100644
--- a/gcc/config/mips/mips.opt
+++ b/gcc/config/mips/mips.opt
@@ -404,6 +404,10 @@ mtune=
Target RejectNegative Joined Var(mips_tune_option) ToLower Enum(mips_arch_opt_value)
-mtune=PROCESSOR Optimize the output for PROCESSOR.
+munaligned-access
+Target Var(TARGET_UNALIGNED_ACCESS) Init(1)
+Generate code with unaligned load store, valid for MIPS R6.
+
muninit-const-in-rodata
Target Var(TARGET_UNINIT_CONST_IN_RODATA)
Put uninitialized constants in ROM (needs -membedded-data).
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 546e95453c1..27730d1a0de 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -1059,6 +1059,7 @@ Objective-C and Objective-C++ Dialects}.
-mcheck-zero-division -mno-check-zero-division @gol
-mdivide-traps -mdivide-breaks @gol
-mload-store-pairs -mno-load-store-pairs @gol
+-munaligned-access -mno-unaligned-access @gol
-mmemcpy -mno-memcpy -mlong-calls -mno-long-calls @gol
-mmad -mno-mad -mimadd -mno-imadd -mfused-madd -mno-fused-madd -nocpp @gol
-mfix-24k -mno-fix-24k @gol
@@ -24967,6 +24968,15 @@ instructions to enable load/store bonding. This option is enabled by
default but only takes effect when the selected architecture is known
to support bonding.
+@item -munaligned-access
+@itemx -mno-unaligned-access
+@opindex munaligned-access
+@opindex mno-unaligned-access
+Enable (disable) direct unaligned access for MIPS Release 6.
+MIPSr6 requires load/store unaligned-access support,
+by hardware or trap&emulate.
+So @option{-mno-unaligned-access} may be needed by kernel.
+
@item -mmemcpy
@itemx -mno-memcpy
@opindex mmemcpy
diff --git a/gcc/testsuite/gcc.target/mips/mips.exp b/gcc/testsuite/gcc.target/mips/mips.exp
index 01292316944..cb1ee7d71b5 100644
--- a/gcc/testsuite/gcc.target/mips/mips.exp
+++ b/gcc/testsuite/gcc.target/mips/mips.exp
@@ -264,6 +264,7 @@ set mips_option_groups {
frame-header "-mframe-header-opt|-mno-frame-header-opt"
stack-protector "-fstack-protector"
stdlib "REQUIRES_STDLIB"
+ unaligned-access "-m(no-|)unaligned-access"
}
for { set option 0 } { $option < 32 } { incr option } {
diff --git a/gcc/testsuite/gcc.target/mips/unaligned-2.c b/gcc/testsuite/gcc.target/mips/unaligned-2.c
new file mode 100644
index 00000000000..8679afac400
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/unaligned-2.c
@@ -0,0 +1,53 @@
+/* { dg-options "isa_rev>=6 -mgp64" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+/* { dg-final { scan-assembler-not "\tsb\t" } } */
+/* { dg-final { scan-assembler-not "\tsh\t" } } */
+/* { dg-final { scan-assembler-not "\tlb\t" } } */
+/* { dg-final { scan-assembler-not "\tlh\t" } } */
+/* { dg-final { scan-assembler-not "\tswl\t" } } */
+/* { dg-final { scan-assembler-not "\tswr\t" } } */
+/* { dg-final { scan-assembler-not "\tlwl\t" } } */
+/* { dg-final { scan-assembler-not "\tlwr\t" } } */
+/* { dg-final { scan-assembler-not "\tsdl\t" } } */
+/* { dg-final { scan-assembler-not "\tsdr\t" } } */
+/* { dg-final { scan-assembler-not "\tldl\t" } } */
+/* { dg-final { scan-assembler-not "\tldr\t" } } */
+/* { dg-final { scan-assembler-times "\tsw\t" 1 } } */
+/* { dg-final { scan-assembler-times "\tlw\t" 1 } } */
+/* { dg-final { scan-assembler-times "\tsd\t" 1 } } */
+/* { dg-final { scan-assembler-times "\tld\t" 1 } } */
+/* { dg-final { scan-assembler-not "\tnop" } } */
+
+/* Test to make sure we produce the unaligned load/store for
+ both 64bit and 32bits sized accesses. */
+
+struct s
+{
+ char c;
+ int i;
+ long long l;
+} __attribute__ ((packed)) s __attribute__((aligned(1) ));
+
+NOMIPS16 void
+sd (long long l)
+{
+ s.l = l;
+}
+
+NOMIPS16 long long
+ld ()
+{
+ return s.l;
+}
+
+NOMIPS16 void
+sw (int i)
+{
+ s.i = i;
+}
+
+NOMIPS16 int
+lw ()
+{
+ return s.i;
+}
diff --git a/gcc/testsuite/gcc.target/mips/unaligned-3.c b/gcc/testsuite/gcc.target/mips/unaligned-3.c
new file mode 100644
index 00000000000..d0fbe19de50
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/unaligned-3.c
@@ -0,0 +1,53 @@
+/* { dg-options "isa_rev>=6 -mgp64 -mno-unaligned-access" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+/* { dg-final { scan-assembler-times "\tsb\t" 12 } } */
+/* { dg-final { scan-assembler-times "\tlbu\t" 12 } } */
+/* { dg-final { scan-assembler-not "\tsh\t" } } */
+/* { dg-final { scan-assembler-not "\tlh\t" } } */
+/* { dg-final { scan-assembler-not "\tsw\t" } } */
+/* { dg-final { scan-assembler-not "\tlw\t" } } */
+/* { dg-final { scan-assembler-not "\tsd\t" } } */
+/* { dg-final { scan-assembler-not "\tld\t" } } */
+/* { dg-final { scan-assembler-not "\tswl\t" } } */
+/* { dg-final { scan-assembler-not "\tswr\t" } } */
+/* { dg-final { scan-assembler-not "\tlwl\t" } } */
+/* { dg-final { scan-assembler-not "\tlwr\t" } } */
+/* { dg-final { scan-assembler-not "\tsdl\t" } } */
+/* { dg-final { scan-assembler-not "\tsdr\t" } } */
+/* { dg-final { scan-assembler-not "\tldl\t" } } */
+/* { dg-final { scan-assembler-not "\tldr\t" } } */
+/* { dg-final { scan-assembler-not "\tnop" } } */
+
+/* Test to make sure we produce the unaligned load/store for
+ both 64bit and 32bits sized accesses. */
+
+struct s
+{
+ char c;
+ int i;
+ long long l;
+} __attribute__ ((packed)) s __attribute__((aligned(1) ));
+
+NOMIPS16 void
+sd (long long l)
+{
+ s.l = l;
+}
+
+NOMIPS16 long long
+ld ()
+{
+ return s.l;
+}
+
+NOMIPS16 void
+sw (int i)
+{
+ s.i = i;
+}
+
+NOMIPS16 int
+lw ()
+{
+ return s.i;
+}
--
2.20.1
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] MIPS: R6: load/store can process unaligned address
2021-02-28 7:16 [PATCH] MIPS: R6: load/store can process unaligned address YunQiang Su
@ 2021-03-12 10:30 ` YunQiang Su
2021-03-22 2:27 ` YunQiang Su
0 siblings, 1 reply; 3+ messages in thread
From: YunQiang Su @ 2021-03-12 10:30 UTC (permalink / raw)
To: YunQiang Su
Cc: gcc-patches, Maciej W. Rozycki, Jeff Law, Matthias Klose, Jiaxun Yang
ping.
YunQiang Su <yunqiang.su@cipunited.com> 于2021年2月28日周日 下午3:17写道:
>
> MIPS release 6 requires the lw/ld/sw/sd can work with
> unaligned address, while it can be implemented by
> full hardware or trap&emulate.
>
> Since it is may be fully done by hardware, we add an
> option -m(no-)unaligned-access, the kernel may need it.
>
> gcc/ChangeLog:
>
> * config/mips/mips.h (ISA_HAS_UNALIGNED_ACCESS):
> (STRICT_ALIGNMENT): R6 can unaligned access.
> * config/mips/mips.md (movmisalign<mode>): Likewise.
> * config/mips/mips.opt: add -m(no-)unaligned-access
> * doc/invoke.texi: Likewise.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.target/mips/mips.exp: add unaligned-access
> * gcc.target/mips/unaligned-2.c: New test.
> * gcc.target/mips/unaligned-3.c: New test.
> ---
> gcc/config/mips/mips.h | 6 ++-
> gcc/config/mips/mips.md | 10 ++++
> gcc/config/mips/mips.opt | 4 ++
> gcc/doc/invoke.texi | 10 ++++
> gcc/testsuite/gcc.target/mips/mips.exp | 1 +
> gcc/testsuite/gcc.target/mips/unaligned-2.c | 53 +++++++++++++++++++++
> gcc/testsuite/gcc.target/mips/unaligned-3.c | 53 +++++++++++++++++++++
> 7 files changed, 136 insertions(+), 1 deletion(-)
> create mode 100644 gcc/testsuite/gcc.target/mips/unaligned-2.c
> create mode 100644 gcc/testsuite/gcc.target/mips/unaligned-3.c
>
> diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
> index b4a60a55d80..38c39f79ee2 100644
> --- a/gcc/config/mips/mips.h
> +++ b/gcc/config/mips/mips.h
> @@ -226,6 +226,10 @@ struct mips_cpu_info {
> && (mips_isa_rev >= 6 \
> || ISA_HAS_MSA))
>
> +/* ISA load/store instructions can handle unaligned address */
> +#define ISA_HAS_UNALIGNED_ACCESS (TARGET_UNALIGNED_ACCESS \
> + && (mips_isa_rev >= 6))
> +
> /* The ISA compression flags that are currently in effect. */
> #define TARGET_COMPRESSION (target_flags & (MASK_MIPS16 | MASK_MICROMIPS))
>
> @@ -1665,7 +1669,7 @@ FP_ASM_SPEC "\
> (ISA_HAS_MSA ? BITS_PER_MSA_REG : LONG_DOUBLE_TYPE_SIZE)
>
> /* All accesses must be aligned. */
> -#define STRICT_ALIGNMENT 1
> +#define STRICT_ALIGNMENT (!ISA_HAS_UNALIGNED_ACCESS)
>
> /* Define this if you wish to imitate the way many other C compilers
> handle alignment of bitfields and the structures that contain
> diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
> index eef3cfd50a8..40e29c60432 100644
> --- a/gcc/config/mips/mips.md
> +++ b/gcc/config/mips/mips.md
> @@ -4459,6 +4459,16 @@ (define_insn "mov_<store>r"
> [(set_attr "move_type" "store")
> (set_attr "mode" "<MODE>")])
>
> +;; Unaligned direct access
> +(define_expand "movmisalign<mode>"
> + [(set (match_operand:JOIN_MODE 0)
> + (match_operand:JOIN_MODE 1))]
> + "ISA_HAS_UNALIGNED_ACCESS"
> +{
> + if (mips_legitimize_move (<MODE>mode, operands[0], operands[1]))
> + DONE;
> +})
> +
> ;; An instruction to calculate the high part of a 64-bit SYMBOL_ABSOLUTE.
> ;; The required value is:
> ;;
> diff --git a/gcc/config/mips/mips.opt b/gcc/config/mips/mips.opt
> index 6af8037e9bd..ebb4c616401 100644
> --- a/gcc/config/mips/mips.opt
> +++ b/gcc/config/mips/mips.opt
> @@ -404,6 +404,10 @@ mtune=
> Target RejectNegative Joined Var(mips_tune_option) ToLower Enum(mips_arch_opt_value)
> -mtune=PROCESSOR Optimize the output for PROCESSOR.
>
> +munaligned-access
> +Target Var(TARGET_UNALIGNED_ACCESS) Init(1)
> +Generate code with unaligned load store, valid for MIPS R6.
> +
> muninit-const-in-rodata
> Target Var(TARGET_UNINIT_CONST_IN_RODATA)
> Put uninitialized constants in ROM (needs -membedded-data).
> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> index 546e95453c1..27730d1a0de 100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -1059,6 +1059,7 @@ Objective-C and Objective-C++ Dialects}.
> -mcheck-zero-division -mno-check-zero-division @gol
> -mdivide-traps -mdivide-breaks @gol
> -mload-store-pairs -mno-load-store-pairs @gol
> +-munaligned-access -mno-unaligned-access @gol
> -mmemcpy -mno-memcpy -mlong-calls -mno-long-calls @gol
> -mmad -mno-mad -mimadd -mno-imadd -mfused-madd -mno-fused-madd -nocpp @gol
> -mfix-24k -mno-fix-24k @gol
> @@ -24967,6 +24968,15 @@ instructions to enable load/store bonding. This option is enabled by
> default but only takes effect when the selected architecture is known
> to support bonding.
>
> +@item -munaligned-access
> +@itemx -mno-unaligned-access
> +@opindex munaligned-access
> +@opindex mno-unaligned-access
> +Enable (disable) direct unaligned access for MIPS Release 6.
> +MIPSr6 requires load/store unaligned-access support,
> +by hardware or trap&emulate.
> +So @option{-mno-unaligned-access} may be needed by kernel.
> +
> @item -mmemcpy
> @itemx -mno-memcpy
> @opindex mmemcpy
> diff --git a/gcc/testsuite/gcc.target/mips/mips.exp b/gcc/testsuite/gcc.target/mips/mips.exp
> index 01292316944..cb1ee7d71b5 100644
> --- a/gcc/testsuite/gcc.target/mips/mips.exp
> +++ b/gcc/testsuite/gcc.target/mips/mips.exp
> @@ -264,6 +264,7 @@ set mips_option_groups {
> frame-header "-mframe-header-opt|-mno-frame-header-opt"
> stack-protector "-fstack-protector"
> stdlib "REQUIRES_STDLIB"
> + unaligned-access "-m(no-|)unaligned-access"
> }
>
> for { set option 0 } { $option < 32 } { incr option } {
> diff --git a/gcc/testsuite/gcc.target/mips/unaligned-2.c b/gcc/testsuite/gcc.target/mips/unaligned-2.c
> new file mode 100644
> index 00000000000..8679afac400
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/mips/unaligned-2.c
> @@ -0,0 +1,53 @@
> +/* { dg-options "isa_rev>=6 -mgp64" } */
> +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
> +/* { dg-final { scan-assembler-not "\tsb\t" } } */
> +/* { dg-final { scan-assembler-not "\tsh\t" } } */
> +/* { dg-final { scan-assembler-not "\tlb\t" } } */
> +/* { dg-final { scan-assembler-not "\tlh\t" } } */
> +/* { dg-final { scan-assembler-not "\tswl\t" } } */
> +/* { dg-final { scan-assembler-not "\tswr\t" } } */
> +/* { dg-final { scan-assembler-not "\tlwl\t" } } */
> +/* { dg-final { scan-assembler-not "\tlwr\t" } } */
> +/* { dg-final { scan-assembler-not "\tsdl\t" } } */
> +/* { dg-final { scan-assembler-not "\tsdr\t" } } */
> +/* { dg-final { scan-assembler-not "\tldl\t" } } */
> +/* { dg-final { scan-assembler-not "\tldr\t" } } */
> +/* { dg-final { scan-assembler-times "\tsw\t" 1 } } */
> +/* { dg-final { scan-assembler-times "\tlw\t" 1 } } */
> +/* { dg-final { scan-assembler-times "\tsd\t" 1 } } */
> +/* { dg-final { scan-assembler-times "\tld\t" 1 } } */
> +/* { dg-final { scan-assembler-not "\tnop" } } */
> +
> +/* Test to make sure we produce the unaligned load/store for
> + both 64bit and 32bits sized accesses. */
> +
> +struct s
> +{
> + char c;
> + int i;
> + long long l;
> +} __attribute__ ((packed)) s __attribute__((aligned(1) ));
> +
> +NOMIPS16 void
> +sd (long long l)
> +{
> + s.l = l;
> +}
> +
> +NOMIPS16 long long
> +ld ()
> +{
> + return s.l;
> +}
> +
> +NOMIPS16 void
> +sw (int i)
> +{
> + s.i = i;
> +}
> +
> +NOMIPS16 int
> +lw ()
> +{
> + return s.i;
> +}
> diff --git a/gcc/testsuite/gcc.target/mips/unaligned-3.c b/gcc/testsuite/gcc.target/mips/unaligned-3.c
> new file mode 100644
> index 00000000000..d0fbe19de50
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/mips/unaligned-3.c
> @@ -0,0 +1,53 @@
> +/* { dg-options "isa_rev>=6 -mgp64 -mno-unaligned-access" } */
> +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
> +/* { dg-final { scan-assembler-times "\tsb\t" 12 } } */
> +/* { dg-final { scan-assembler-times "\tlbu\t" 12 } } */
> +/* { dg-final { scan-assembler-not "\tsh\t" } } */
> +/* { dg-final { scan-assembler-not "\tlh\t" } } */
> +/* { dg-final { scan-assembler-not "\tsw\t" } } */
> +/* { dg-final { scan-assembler-not "\tlw\t" } } */
> +/* { dg-final { scan-assembler-not "\tsd\t" } } */
> +/* { dg-final { scan-assembler-not "\tld\t" } } */
> +/* { dg-final { scan-assembler-not "\tswl\t" } } */
> +/* { dg-final { scan-assembler-not "\tswr\t" } } */
> +/* { dg-final { scan-assembler-not "\tlwl\t" } } */
> +/* { dg-final { scan-assembler-not "\tlwr\t" } } */
> +/* { dg-final { scan-assembler-not "\tsdl\t" } } */
> +/* { dg-final { scan-assembler-not "\tsdr\t" } } */
> +/* { dg-final { scan-assembler-not "\tldl\t" } } */
> +/* { dg-final { scan-assembler-not "\tldr\t" } } */
> +/* { dg-final { scan-assembler-not "\tnop" } } */
> +
> +/* Test to make sure we produce the unaligned load/store for
> + both 64bit and 32bits sized accesses. */
> +
> +struct s
> +{
> + char c;
> + int i;
> + long long l;
> +} __attribute__ ((packed)) s __attribute__((aligned(1) ));
> +
> +NOMIPS16 void
> +sd (long long l)
> +{
> + s.l = l;
> +}
> +
> +NOMIPS16 long long
> +ld ()
> +{
> + return s.l;
> +}
> +
> +NOMIPS16 void
> +sw (int i)
> +{
> + s.i = i;
> +}
> +
> +NOMIPS16 int
> +lw ()
> +{
> + return s.i;
> +}
> --
> 2.20.1
>
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] MIPS: R6: load/store can process unaligned address
2021-03-12 10:30 ` YunQiang Su
@ 2021-03-22 2:27 ` YunQiang Su
0 siblings, 0 replies; 3+ messages in thread
From: YunQiang Su @ 2021-03-22 2:27 UTC (permalink / raw)
To: YunQiang Su
Cc: gcc-patches, Maciej W. Rozycki, Jeff Law, Matthias Klose, Jiaxun Yang
Ping for this patch again.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2021-03-22 2:27 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-28 7:16 [PATCH] MIPS: R6: load/store can process unaligned address YunQiang Su
2021-03-12 10:30 ` YunQiang Su
2021-03-22 2:27 ` YunQiang Su
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).