From: Yongbok Kim <yongbok.kim@imgtec.com>
To: Leon Alrae <leon.alrae@imgtec.com>, qemu-devel@nongnu.org
Cc: james.hogan@imgtec.com, aurelien@aurel32.net, rth@twiddle.net
Subject: Re: [Qemu-devel] [PATCH v4 14/21] target-mips: add AUI, LSA and PCREL instruction families
Date: Mon, 13 Oct 2014 14:37:48 +0100 [thread overview]
Message-ID: <543BD5AC.2030106@imgtec.com> (raw)
In-Reply-To: <1412765732-45369-15-git-send-email-leon.alrae@imgtec.com>
I have just few minor comments.
Reviewed-by: Yongbok Kim <yongbok.kim@imgtec.com>
regards,
Yongbok
On 08/10/2014 11:55, Leon Alrae wrote:
> Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
> ---
> v3:
> * use sextract32 instead of open coding the bit field extraction
> * replace _i64 with _tl in DAHI, DATI and DAUI
> * fix misleading LDPC comment
> ---
> disas/mips.c | 42 ++++++++++-
> target-mips/translate.c | 197 +++++++++++++++++++++++++++++++++++++++++++++---
> 2 files changed, 225 insertions(+), 14 deletions(-)
>
> diff --git a/disas/mips.c b/disas/mips.c
> index 8234369..091f4e2 100644
> --- a/disas/mips.c
> +++ b/disas/mips.c
> @@ -407,6 +407,12 @@ struct mips_opcode
> "+3" UDI immediate bits 6-20
> "+4" UDI immediate bits 6-25
>
> + R6 immediates/displacements :
> + (adding suffix to 'o' to avoid adding new characters)
> + "+o" 9 bits immediate/displacement (shift = 7)
> + "+o1" 18 bits immediate/displacement (shift = 0)
> + "+o2" 19 bits immediate/displacement (shift = 0)
> +
> Other:
> "()" parens surrounding optional value
> "," separates operands
> @@ -1217,6 +1223,17 @@ const struct mips_opcode mips_builtin_opcodes[] =
> them first. The assemblers uses a hash table based on the
> instruction name anyhow. */
> /* name, args, match, mask, pinfo, membership */
> +{"lwpc", "s,+o2", 0xec080000, 0xfc180000, WR_d, 0, I32R6},
> +{"lwupc", "s,+o2", 0xec100000, 0xfc180000, WR_d, 0, I32R6},
I64R6
> +{"ldpc", "s,+o1", 0xec180000, 0xfc1c0000, WR_d, 0, I64R6},
> +{"addiupc", "s,+o2", 0xec000000, 0xfc180000, WR_d, 0, I32R6},
> +{"auipc", "s,u", 0xec1e0000, 0xfc1f0000, WR_d, 0, I32R6},
> +{"aluipc", "s,u", 0xec1f0000, 0xfc1f0000, WR_d, 0, I32R6},
> +{"daui", "s,t,u", 0x74000000, 0xfc000000, RD_s|WR_t, 0, I64R6},
> +{"dahi", "s,u", 0x04060000, 0xfc1f0000, RD_s, 0, I64R6},
> +{"dati", "s,u", 0x041e0000, 0xfc1f0000, RD_s, 0, I64R6},
> +{"lsa", "d,s,t", 0x00000005, 0xfc00073f, WR_d|RD_s|RD_t, 0, I32R6},
> +{"dlsa", "d,s,t", 0x00000015, 0xfc00073f, WR_d|RD_s|RD_t, 0, I64R6},
> {"clz", "U,s", 0x00000050, 0xfc1f07ff, WR_d|RD_s, 0, I32R6},
> {"clo", "U,s", 0x00000051, 0xfc1f07ff, WR_d|RD_s, 0, I32R6},
> {"dclz", "U,s", 0x00000052, 0xfc1f07ff, WR_d|RD_s, 0, I64R6},
> @@ -1822,6 +1839,7 @@ const struct mips_opcode mips_builtin_opcodes[] =
> {"lld", "t,o(b)", 0xd0000000, 0xfc000000, LDD|RD_b|WR_t, 0, I3 },
> {"lld", "t,A(b)", 0, (int) M_LLD_AB, INSN_MACRO, 0, I3 },
> {"lui", "t,u", 0x3c000000, 0xffe00000, WR_t, 0, I1 },
> +{"aui", "s,t,u", 0x3c000000, 0xfc000000, RD_s|WR_t, 0, I32R6},
> {"luxc1", "D,t(b)", 0x4c000005, 0xfc00f83f, LDD|WR_D|RD_t|RD_b|FP_D, 0, I5|I33|N55},
> {"lw", "t,o(b)", 0x8c000000, 0xfc000000, LDD|RD_b|WR_t, 0, I1 },
> {"lw", "t,A(b)", 0, (int) M_LW_AB, INSN_MACRO, 0, I1 },
> @@ -3645,10 +3663,28 @@ print_insn_args (const char *d,
> break;
>
> case 'o':
> - delta = (l >> OP_SH_DELTA_R6) & OP_MASK_DELTA_R6;
> - if (delta & 0x8000) {
> - delta |= ~0xffff;
> + switch (*(d+1)) {
> + case '1':
> + d++;
> + delta = l & ((1 << 18) - 1);
> + if (delta & 0x20000) {
> + delta |= ~0x1ffff;
> + }
> + break;
> + case '2':
> + d++;
> + delta = l & ((1 << 19) - 1);
> + if (delta & 0x40000) {
> + delta |= ~0x3ffff;
> + }
> + break;
> + default:
> + delta = (l >> OP_SH_DELTA_R6) & OP_MASK_DELTA_R6;
> + if (delta & 0x8000) {
> + delta |= ~0xffff;
> + }
> }
> +
> (*info->fprintf_func) (info->stream, "%d", delta);
> break;
>
> diff --git a/target-mips/translate.c b/target-mips/translate.c
> index 06ececb..6f64c47 100644
> --- a/target-mips/translate.c
> +++ b/target-mips/translate.c
> @@ -75,6 +75,7 @@ enum {
> OPC_BGTZ = (0x07 << 26),
> OPC_BGTZL = (0x17 << 26),
> OPC_JALX = (0x1D << 26), /* MIPS 16 only */
> + OPC_DAUI = (0x1D << 26),
> OPC_JALXS = OPC_JALX | 0x5,
> /* Load and stores */
> OPC_LDL = (0x1A << 26),
> @@ -141,8 +142,25 @@ enum {
> /* Cache and prefetch */
> OPC_CACHE = (0x2F << 26),
> OPC_PREF = (0x33 << 26),
> - /* Reserved major opcode */
> - OPC_MAJOR3B_RESERVED = (0x3B << 26),
> + /* PC-relative address computation / loads */
> + OPC_PCREL = (0x3B << 26),
> +};
> +
> +/* PC-relative address computation / loads */
> +#define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
> +#define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
There must be better name for this macro.
It confused me that was looking like 31 and 30 bits.
Just naming though...
> +enum {
> + /* Instructions determined by bits 19 and 20 */
> + OPC_ADDIUPC = OPC_PCREL | (0 << 19),
> + R6_OPC_LWPC = OPC_PCREL | (1 << 19),
> + OPC_LWUPC = OPC_PCREL | (2 << 19),
> +
> + /* Instructions determined by bits 16 ... 20 */
> + OPC_AUIPC = OPC_PCREL | (0x1e << 16),
> + OPC_ALUIPC = OPC_PCREL | (0x1f << 16),
> +
> + /* Other */
> + R6_OPC_LDPC = OPC_PCREL | (6 << 18),
> };
>
> /* MIPS special opcodes */
> @@ -231,7 +249,6 @@ enum {
> OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
> OPC_SYNC = 0x0F | OPC_SPECIAL,
>
> - OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
> OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
> OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
> OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
> @@ -266,6 +283,9 @@ enum {
> R6_OPC_DCLZ = 0x12 | OPC_SPECIAL,
> R6_OPC_DCLO = 0x13 | OPC_SPECIAL,
> R6_OPC_SDBBP = 0x0e | OPC_SPECIAL,
> +
> + OPC_LSA = 0x05 | OPC_SPECIAL,
> + OPC_DLSA = 0x15 | OPC_SPECIAL,
> };
>
> /* Multiplication variants of the vr54xx. */
> @@ -309,6 +329,9 @@ enum {
> OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
> OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
> OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
> +
> + OPC_DAHI = (0x06 << 16) | OPC_REGIMM,
> + OPC_DATI = (0x1e << 16) | OPC_REGIMM,
> };
>
> /* Special2 opcodes */
> @@ -2162,8 +2185,15 @@ static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
> regnames[rs], uimm);
> break;
> case OPC_LUI:
> - tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
> - MIPS_DEBUG("lui %s, " TARGET_FMT_lx, regnames[rt], uimm);
> + if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
> + /* OPC_AUI */
> + tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
> + tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
> + MIPS_DEBUG("aui %s, %s, %04x", regnames[rt], regnames[rs], imm);
> + } else {
> + tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
> + MIPS_DEBUG("lui %s, " TARGET_FMT_lx, regnames[rt], uimm);
> + }
> break;
>
> default:
> @@ -2767,6 +2797,77 @@ static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
> MIPS_DEBUG("%s %s", opn, regnames[reg]);
> }
>
> +static inline void gen_r6_ld(target_long addr, int reg, int memidx,
> + TCGMemOp memop)
> +{
> + TCGv t0 = tcg_const_tl(addr);
> + tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
> + gen_store_gpr(t0, reg);
> + tcg_temp_free(t0);
> +}
> +
> +static inline void gen_pcrel(DisasContext *ctx, int rs, int16_t imm)
> +{
> + target_long offset;
> + target_long addr;
> +
> + switch (MASK_OPC_PCREL_TOP2BITS(ctx->opcode)) {
> + case OPC_ADDIUPC:
> + if (rs != 0) {
> + offset = sextract32(ctx->opcode << 2, 0, 21);
> + addr = addr_add(ctx, ctx->pc, offset);
> + tcg_gen_movi_tl(cpu_gpr[rs], addr);
> + }
> + break;
> + case R6_OPC_LWPC:
> + offset = sextract32(ctx->opcode << 2, 0, 21);
> + addr = addr_add(ctx, ctx->pc, offset);
> + gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
> + break;
> +#if defined(TARGET_MIPS64)
> + case OPC_LWUPC:
> + check_mips_64(ctx);
> + offset = sextract32(ctx->opcode << 2, 0, 21);
> + addr = addr_add(ctx, ctx->pc, offset);
> + gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
> + break;
> +#endif
> + default:
> + switch (MASK_OPC_PCREL_TOP5BITS(ctx->opcode)) {
> + case OPC_AUIPC:
> + if (rs != 0) {
> + offset = imm << 16;
> + addr = addr_add(ctx, ctx->pc, offset);
> + tcg_gen_movi_tl(cpu_gpr[rs], addr);
> + }
> + break;
> + case OPC_ALUIPC:
> + if (rs != 0) {
> + offset = imm << 16;
> + addr = ~0xFFFF & addr_add(ctx, ctx->pc, offset);
> + tcg_gen_movi_tl(cpu_gpr[rs], addr);
> + }
> + break;
> +#if defined(TARGET_MIPS64)
> + case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
> + case R6_OPC_LDPC + (1 << 16):
> + case R6_OPC_LDPC + (2 << 16):
> + case R6_OPC_LDPC + (3 << 16):
> + check_mips_64(ctx);
> + offset = sextract32(ctx->opcode << 3, 0, 21);
> + addr = addr_add(ctx, (ctx->pc & ~0x7), offset);
> + gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
> + break;
> +#endif
> + default:
> + MIPS_INVAL("OPC_PCREL");
> + generate_exception(ctx, EXCP_RI);
> + break;
> + }
> + break;
> + }
> +}
> +
> static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
> {
> const char *opn = "r6 mul/div";
> @@ -15097,6 +15198,20 @@ static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
>
> op1 = MASK_SPECIAL(ctx->opcode);
> switch (op1) {
> + case OPC_LSA:
> + if (rd != 0) {
> + int imm2 = extract32(ctx->opcode, 6, 3);
> + TCGv t0 = tcg_temp_new();
> + TCGv t1 = tcg_temp_new();
> + gen_load_gpr(t0, rs);
> + gen_load_gpr(t1, rt);
> + tcg_gen_shli_tl(t0, t0, imm2 + 1);
> + tcg_gen_add_tl(t0, t0, t1);
> + tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
> + tcg_temp_free(t1);
> + tcg_temp_free(t0);
> + }
> + break;
> case OPC_MULT ... OPC_DIVU:
> op2 = MASK_R6_MULDIV(ctx->opcode);
> switch (op2) {
> @@ -15134,6 +15249,20 @@ static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
> generate_exception(ctx, EXCP_DBp);
> break;
> #if defined(TARGET_MIPS64)
> + case OPC_DLSA:
> + check_mips_64(ctx);
> + if (rd != 0) {
> + int imm2 = extract32(ctx->opcode, 6, 3);
> + TCGv t0 = tcg_temp_new();
> + TCGv t1 = tcg_temp_new();
> + gen_load_gpr(t0, rs);
> + gen_load_gpr(t1, rt);
> + tcg_gen_shli_tl(t0, t0, imm2 + 1);
> + tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
> + tcg_temp_free(t1);
> + tcg_temp_free(t0);
> + }
> + break;
> case R6_OPC_DCLO:
> case R6_OPC_DCLZ:
> if (rt == 0 && sa == 1) {
> @@ -15319,13 +15448,18 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
> case OPC_TNE:
> gen_trap(ctx, op1, rs, rt, -1);
> break;
> - case OPC_PMON: /* Pmon entry point, also R4010 selsl */
> + case OPC_LSA: /* OPC_PMON */
> + if (ctx->insn_flags & ISA_MIPS32R6) {
> + decode_opc_special_r6(env, ctx);
> + } else {
> + /* Pmon entry point, also R4010 selsl */
indentation :)
> #ifdef MIPS_STRICT_STANDARD
> MIPS_INVAL("PMON / selsl");
> generate_exception(ctx, EXCP_RI);
> #else
> gen_helper_0e0i(pmon, sa);
> #endif
> + }
> break;
> case OPC_SYSCALL:
> generate_exception(ctx, EXCP_SYSCALL);
> @@ -16297,6 +16431,24 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx)
> check_dsp(ctx);
> gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2);
> break;
> +#if defined(TARGET_MIPS64)
> + case OPC_DAHI:
> + check_insn(ctx, ISA_MIPS32R6);
> + check_mips_64(ctx);
> + if (rs != 0) {
> + tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
> + }
> + MIPS_DEBUG("dahi %s, %04x", regnames[rs], imm);
> + break;
> + case OPC_DATI:
> + check_insn(ctx, ISA_MIPS32R6);
> + check_mips_64(ctx);
> + if (rs != 0) {
> + tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
> + }
> + MIPS_DEBUG("dati %s, %04x", regnames[rs], imm);
> + break;
> +#endif
> default: /* Invalid */
> MIPS_INVAL("regimm");
> generate_exception(ctx, EXCP_RI);
> @@ -16409,7 +16561,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx)
> gen_slt_imm(ctx, op, rt, rs, imm);
> break;
> case OPC_ANDI: /* Arithmetic with immediate opcode */
> - case OPC_LUI:
> + case OPC_LUI: /* OPC_AUI */
> case OPC_ORI:
> case OPC_XORI:
> gen_logic_imm(ctx, op, rt, rs, imm);
> @@ -16707,14 +16859,37 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx)
> }
> break;
> #endif
> - case OPC_JALX:
> - check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
> - offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
> - gen_compute_branch(ctx, op, 4, rs, rt, offset);
> + case OPC_DAUI: /* OPC_JALX */
> + if (ctx->insn_flags & ISA_MIPS32R6) {
> +#if defined(TARGET_MIPS64)
> + /* OPC_DAUI */
> + check_mips_64(ctx);
> + if (rt != 0) {
> + TCGv t0 = tcg_temp_new();
> + gen_load_gpr(t0, rs);
> + tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
> + tcg_temp_free(t0);
> + }
> + MIPS_DEBUG("daui %s, %s, %04x", regnames[rt], regnames[rs], imm);
> +#else
> + generate_exception(ctx, EXCP_RI);
> + MIPS_INVAL("major opcode");
> +#endif
> + } else {
> + /* OPC_JALX */
> + check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
> + offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
> + gen_compute_branch(ctx, op, 4, rs, rt, offset);
> + }
> break;
> case OPC_MDMX:
> check_insn(ctx, ASE_MDMX);
> /* MDMX: Not implemented. */
> + break;
> + case OPC_PCREL:
> + check_insn(ctx, ISA_MIPS32R6);
> + gen_pcrel(ctx, rs, imm);
> + break;
> default: /* Invalid */
> MIPS_INVAL("major opcode");
> generate_exception(ctx, EXCP_RI);
next prev parent reply other threads:[~2014-10-13 13:38 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-10-08 10:55 [Qemu-devel] [PATCH v4 00/21] target-mips: add MIPS64R6 Instruction Set support Leon Alrae
2014-10-08 10:55 ` [Qemu-devel] [PATCH v4 01/21] target-mips: define ISA_MIPS64R6 Leon Alrae
2014-10-08 10:55 ` [Qemu-devel] [PATCH v4 02/21] target-mips: signal RI Exception on instructions removed in R6 Leon Alrae
2014-10-08 10:55 ` [Qemu-devel] [PATCH v4 03/21] target-mips: add SELEQZ and SELNEZ instructions Leon Alrae
2014-10-08 10:55 ` [Qemu-devel] [PATCH v4 04/21] target-mips: move LL and SC instructions Leon Alrae
2014-10-08 10:55 ` [Qemu-devel] [PATCH v4 05/21] target-mips: extract decode_opc_special* from decode_opc Leon Alrae
2014-10-08 10:55 ` [Qemu-devel] [PATCH v4 06/21] target-mips: split decode_opc_special* into *_r6 and *_legacy Leon Alrae
2014-10-08 10:55 ` [Qemu-devel] [PATCH v4 07/21] target-mips: signal RI Exception on DSP and Loongson instructions Leon Alrae
2014-10-08 10:55 ` [Qemu-devel] [PATCH v4 08/21] target-mips: move PREF, CACHE, LLD and SCD instructions Leon Alrae
2014-10-08 10:55 ` [Qemu-devel] [PATCH v4 09/21] target-mips: redefine Integer Multiply and Divide instructions Leon Alrae
2014-10-08 10:55 ` [Qemu-devel] [PATCH v4 10/21] target-mips: move CLO, DCLO, CLZ, DCLZ, SDBBP and free special2 in R6 Leon Alrae
2014-10-08 10:55 ` [Qemu-devel] [PATCH v4 11/21] target-mips: Status.UX/SX/KX enable 32-bit address wrapping Leon Alrae
2014-10-08 10:55 ` [Qemu-devel] [PATCH v4 12/21] target-mips: add ALIGN, DALIGN, BITSWAP and DBITSWAP instructions Leon Alrae
2014-10-08 10:55 ` [Qemu-devel] [PATCH v4 13/21] target-mips: add compact and CP1 branches Leon Alrae
2014-10-08 10:55 ` [Qemu-devel] [PATCH v4 14/21] target-mips: add AUI, LSA and PCREL instruction families Leon Alrae
2014-10-13 13:37 ` Yongbok Kim [this message]
2014-10-14 11:40 ` Leon Alrae
2014-11-12 21:07 ` Paolo Bonzini
2014-11-13 10:39 ` Leon Alrae
2014-10-08 10:55 ` [Qemu-devel] [PATCH v4 15/21] softfloat: add functions corresponding to IEEE-2008 min/maxNumMag Leon Alrae
2014-10-08 10:55 ` [Qemu-devel] [PATCH v4 16/21] target-mips: add new Floating Point instructions Leon Alrae
2014-10-08 10:55 ` [Qemu-devel] [PATCH v4 17/21] target-mips: add new Floating Point Comparison instructions Leon Alrae
2014-10-08 10:55 ` [Qemu-devel] [PATCH v4 18/21] target-mips: do not allow Status.FR=0 mode in 64-bit FPU Leon Alrae
2014-10-08 10:55 ` [Qemu-devel] [PATCH v4 19/21] target-mips: remove JR, BLTZAL, BGEZAL and add NAL, BAL instructions Leon Alrae
2014-10-08 10:55 ` [Qemu-devel] [PATCH v4 20/21] mips_malta: update malta's pseudo-bootloader - replace JR with JALR Leon Alrae
2014-10-08 10:55 ` [Qemu-devel] [PATCH v4 21/21] target-mips: define a new generic CPU supporting MIPS64 Release 6 ISA Leon Alrae
2014-10-14 9:05 ` Yongbok Kim
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=543BD5AC.2030106@imgtec.com \
--to=yongbok.kim@imgtec.com \
--cc=aurelien@aurel32.net \
--cc=james.hogan@imgtec.com \
--cc=leon.alrae@imgtec.com \
--cc=qemu-devel@nongnu.org \
--cc=rth@twiddle.net \
/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 NNTP newsgroup(s).