diff --git a/apply-patches b/apply-patches new file mode 100644 index 0000000000000000000000000000000000000000..21931ccde1b972a5a3a9997e20a8b771930356a1 --- /dev/null +++ b/apply-patches @@ -0,0 +1,13 @@ +#!/bin/bash + +set -ex + +if [ ! -d loongarch64 ]; then + tar -xf loongarch64.tar.gz +fi + +for p in $(cat loongarch64.conf); do + patch -p1 -s -i loongarch64/$p +done + +rm -rf $0 loongarch64 loongarch64.tar.gz loongarch64.conf diff --git a/golang.spec b/golang.spec index da55871dd402521bf8c4fc4d1deb117b30182425..f7ca933b6fec5cf754ccae5dd5aff2292528bdd5 100644 --- a/golang.spec +++ b/golang.spec @@ -66,11 +66,16 @@ Name: golang Version: 1.21.4 -Release: 30 +Release: 31 Summary: The Go Programming Language License: BSD and Public Domain URL: https://golang.org/ Source0: https://dl.google.com/go/go%{version}.src.tar.gz +%ifarch loongarch64 +Source1: loongarch64.tar.gz +Source2: loongarch64.conf +Source3: apply-patches +%endif %if !%{golang_bootstrap} BuildRequires: gcc-go >= 5 @@ -195,6 +200,13 @@ end %prep %autosetup -n go -p1 +%ifarch loongarch64 +cp %{SOURCE1} . +cp %{SOURCE2} . +cp %{SOURCE3} . +sh ./apply-patches +%endif + %build uname -a cat /proc/cpuinfo @@ -387,6 +399,18 @@ fi %files devel -f go-tests.list -f go-misc.list -f go-src.list %changelog +* Wed Feb 19 2025 Huang Qiqi - 1.21.4-31 +- remove useless relocation +- add additional relocations +- add new relocations numbered 101 to 109 for +- remove unused register alias +- change the LR parameter register +- enable race detector on loong64 +- Mark race functions on loong64 as ABInternal +- delete on-register ABI fallback path for race +- update isUnsupportedVMASize test skip +- update race_linux_loong64.syso + * Sun Jan 26 2025 Vanient - 1.21.4-30 - Type:bugfix - CVE:NA diff --git a/loongarch64.conf b/loongarch64.conf new file mode 100644 index 0000000000000000000000000000000000000000..625a5d36ed365a2a1258c81c5dbe6f9c1428d8d8 --- /dev/null +++ b/loongarch64.conf @@ -0,0 +1,51 @@ +0001-cmd-dist-cmd-link-internal-runtime-add-buildmode-plu.patch +0002-runtime-cmd-go-enable-memory-sanitizer-on-linux-loon.patch +0003-runtime-cmd-go-enable-address-sanitizer-on-linux-loo.patch +0004-internal-sysinfo-print-cpu-type-from-cpuinfo-when-in.patch +0005-cmd-cmd-vendor-pick-up-updates-for-golang.org-x-arch.patch +0006-cmd-internal-objfile-add-loong64-disassembler-suppor.patch +0007-runtime-remove-the-meaningless-offset-of-8-for-duffz.patch +0008-cmd-compiler-remove-the-meaningless-offset-of-8-for-.patch +0009-cmd-internal-obj-loong64-add-atomic-memory-access-in.patch +0010-cmd-compiler-runtime-internal-atomic-optimize-xchg-a.patch +0011-cmd-compiler-runtime-internal-atomic-optimize-xadd-a.patch +0012-cmd-compiler-runtime-internal-atomic-optimize-And-32.patch +0013-cmd-compiler-runtime-internal-atomic-Implementing-xc.patch +0014-cmd-compiler-runtime-internal-atomic-Implementing-xa.patch +0015-cmd-compiler-runtime-internal-atomic-Implementing-An.patch +0016-cmd-internal-obj-loong64-remove-the-invalid-plan9-fo.patch +0017-cmd-internal-obj-loong64-correct-the-instruction-for.patch +0018-cmd-internal-obj-loong64-recheck-jump-offset-boundar.patch +0019-cmd-link-internal-loong64-correct-the-glibc-dynamic-.patch +0020-cmd-link-internal-loadelf-correct-the-relocation-siz.patch +0021-cmd-compile-cmd-internal-runtime-change-the-register.patch +0022-cmd-compile-add-ABI-register-definations-for-loong64.patch +0023-cmd-compile-cmd-internal-runtime-change-registers-on.patch +0024-internal-abi-define-loong64-regABI-constants.patch +0025-cmd-compile-internal-add-register-info-for-loong64-r.patch +0026-cmd-compile-internal-add-spill-support-for-loong64-r.patch +0027-cmd-compile-update-loong64-CALL-ops.patch +0028-runtime-make-duff-device-as-ABIInternal-for-loong64.patch +0029-runtime-support-regABI-and-add-spill-functions-in-ru.patch +0030-reflect-runtime-add-reflect-support-for-regABI-on-lo.patch +0031-internal-bytealg-add-regABI-support-in-bytealg-funct.patch +0032-runtime-add-regABI-support-in-memclr-and-memmove-fun.patch +0033-cmd-internal-obj-set-morestack-arg-spilling-and-rega.patch +0034-cmd-compile-fix-If-lowering-on-loong64.patch +0035-runtime-internal-syscall-use-ABIInternal-for-Syscall.patch +0036-cmd-compile-internal-buildcfg-enable-regABI-on-loong.patch +0037-internal-abi-internal-buildcfg-always-enable-registe.patch +0038-all-delete-loong64-non-register-ABI-fallback-path.patch +0039-cmd-internal-obj-loong64-using-LookupABI-to-find-duf.patch +0040-cmd-internal-cmd-link-unify-the-relocation-naming-st.patch +0041-cmd-link-internal-loadelf-remove-useless-relocation-.patch +0042-cmd-link-internal-loadelf-add-additional-relocations.patch +0043-cmd-link-add-new-relocations-numbered-101-to-109-for.patch +0044-api-add-new-relocations-numbered-101-to-109-for-loon.patch +0045-cmd-internal-obj-loong64-remove-unused-register-alia.patch +0046-cmd-internal-runtime-change-the-LR-parameter-registe.patch +0047-cmd-runtime-enable-race-detector-on-loong64.patch +0048-runtime-Mark-race-functions-on-loong64-as-ABInternal.patch +0049-runtime-delete-on-register-ABI-fallback-path-for-rac.patch +0050-cmd-dist-update-isUnsupportedVMASize-test-skip.patch +0051-runtime-race-update-race_linux_loong64.syso.patch diff --git a/loongarch64/0001-cmd-dist-cmd-link-internal-runtime-add-buildmode-plu.patch b/loongarch64/0001-cmd-dist-cmd-link-internal-runtime-add-buildmode-plu.patch new file mode 100644 index 0000000000000000000000000000000000000000..ba248ae57156b3d10e86622e38d7f8ccac2a1bf7 --- /dev/null +++ b/loongarch64/0001-cmd-dist-cmd-link-internal-runtime-add-buildmode-plu.patch @@ -0,0 +1,1318 @@ +From 4ae46d50b82eb21382fc46b843709e1551593e5a Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Fri, 7 Jul 2023 07:18:59 +0800 +Subject: [PATCH 01/51] cmd/dist, cmd/link, internal, runtime: add + buildmode={plugin,shared} support for linux/loong64. + +Signed-off-by: Guoqi Chen +Change-Id: I0e7843c7d61420af1c59778ad1e0ecc8dc3bca57 +--- + src/cmd/compile/internal/liveness/plive.go | 7 +- + .../compile/internal/ssa/_gen/LOONG64.rules | 85 +++----- + src/cmd/compile/internal/ssa/regalloc.go | 2 + + .../compile/internal/ssa/rewriteLOONG64.go | 190 +++++++++++------- + src/cmd/dist/test.go | 4 +- + src/cmd/internal/obj/loong64/a.out.go | 1 + + src/cmd/internal/obj/loong64/asm.go | 21 ++ + src/cmd/internal/obj/loong64/cnames.go | 1 + + src/cmd/internal/obj/loong64/obj.go | 123 ++++++++++++ + src/cmd/internal/objabi/reloctype.go | 5 + + src/cmd/internal/objabi/reloctype_string.go | 22 +- + src/cmd/link/internal/loong64/asm.go | 59 +++++- + src/internal/platform/supported.go | 4 +- + src/runtime/asm_loong64.s | 11 + + 14 files changed, 382 insertions(+), 153 deletions(-) + +diff --git a/src/cmd/compile/internal/liveness/plive.go b/src/cmd/compile/internal/liveness/plive.go +index 169467e6f5..38273db07d 100644 +--- a/src/cmd/compile/internal/liveness/plive.go ++++ b/src/cmd/compile/internal/liveness/plive.go +@@ -546,7 +546,12 @@ func (lv *liveness) markUnsafePoints() { + v = v.Args[0] + continue + } +- case ssa.Op386MOVLload, ssa.OpARM64MOVWUload, ssa.OpMIPS64MOVWUload, ssa.OpPPC64MOVWZload, ssa.OpWasmI64Load32U: ++ case ssa.Op386MOVLload, ++ ssa.OpARM64MOVWUload, ++ ssa.OpLOONG64MOVWUload, ++ ssa.OpMIPS64MOVWUload, ++ ssa.OpPPC64MOVWZload, ++ ssa.OpWasmI64Load32U: + // Args[0] is the address of the write + // barrier control. Ignore Args[1], + // which is the mem operand. +diff --git a/src/cmd/compile/internal/ssa/_gen/LOONG64.rules b/src/cmd/compile/internal/ssa/_gen/LOONG64.rules +index 4a47c4cd47..b9aaa3ff7f 100644 +--- a/src/cmd/compile/internal/ssa/_gen/LOONG64.rules ++++ b/src/cmd/compile/internal/ssa/_gen/LOONG64.rules +@@ -455,66 +455,31 @@ + (ADDVconst [off1] (MOVVaddr [off2] {sym} ptr)) && is32Bit(off1+int64(off2)) => (MOVVaddr [int32(off1)+int32(off2)] {sym} ptr) + + // fold address into load/store +-(MOVBload [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVBload [off1+int32(off2)] {sym} ptr mem) +-(MOVBUload [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVBUload [off1+int32(off2)] {sym} ptr mem) +-(MOVHload [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVHload [off1+int32(off2)] {sym} ptr mem) +-(MOVHUload [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVHUload [off1+int32(off2)] {sym} ptr mem) +-(MOVWload [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVWload [off1+int32(off2)] {sym} ptr mem) +-(MOVWUload [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVWUload [off1+int32(off2)] {sym} ptr mem) +-(MOVVload [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVVload [off1+int32(off2)] {sym} ptr mem) +-(MOVFload [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVFload [off1+int32(off2)] {sym} ptr mem) +-(MOVDload [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVDload [off1+int32(off2)] {sym} ptr mem) +- +-(MOVBstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) => (MOVBstore [off1+int32(off2)] {sym} ptr val mem) +-(MOVHstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) => (MOVHstore [off1+int32(off2)] {sym} ptr val mem) +-(MOVWstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) => (MOVWstore [off1+int32(off2)] {sym} ptr val mem) +-(MOVVstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) => (MOVVstore [off1+int32(off2)] {sym} ptr val mem) +-(MOVFstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) => (MOVFstore [off1+int32(off2)] {sym} ptr val mem) +-(MOVDstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) => (MOVDstore [off1+int32(off2)] {sym} ptr val mem) +-(MOVBstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVBstorezero [off1+int32(off2)] {sym} ptr mem) +-(MOVHstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVHstorezero [off1+int32(off2)] {sym} ptr mem) +-(MOVWstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVWstorezero [off1+int32(off2)] {sym} ptr mem) +-(MOVVstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVVstorezero [off1+int32(off2)] {sym} ptr mem) +- +-(MOVBload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => +- (MOVBload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) +-(MOVBUload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => +- (MOVBUload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) +-(MOVHload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => +- (MOVHload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) +-(MOVHUload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => +- (MOVHUload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) +-(MOVWload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => +- (MOVWload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) +-(MOVWUload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => +- (MOVWUload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) +-(MOVVload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => +- (MOVVload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) +-(MOVFload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => +- (MOVFload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) +-(MOVDload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => +- (MOVDload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) +- +-(MOVBstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => +- (MOVBstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) +-(MOVHstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => +- (MOVHstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) +-(MOVWstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => +- (MOVWstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) +-(MOVVstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => +- (MOVVstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) +-(MOVFstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => +- (MOVFstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) +-(MOVDstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => +- (MOVDstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) +-(MOVBstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => +- (MOVBstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) +-(MOVHstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => +- (MOVHstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) +-(MOVWstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => +- (MOVWstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) +-(MOVVstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) => +- (MOVVstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) ++// Do not fold global variable access in -dynlink mode, where it will be rewritten ++// to use the GOT via REGTMP, which currently cannot handle large offset. ++(MOV(B|BU|H|HU|W|WU|V|F|D)load [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) ++ && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) => ++ (MOV(B|BU|H|HU|W|WU|V|F|D)load [off1+int32(off2)] {sym} ptr mem) ++ ++(MOV(B|H|W|V|F|D)store [off1] {sym} (ADDVconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) ++ && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) => ++ (MOV(B|H|W|V|F|D)store [off1+int32(off2)] {sym} ptr val mem) ++ ++(MOV(B|H|W|V)storezero [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) ++ && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) => ++ (MOV(B|H|W|V)storezero [off1+int32(off2)] {sym} ptr mem) ++ ++(MOV(B|BU|H|HU|W|WU|V|F|D)load [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) ++ && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) => ++ (MOV(B|BU|H|HU|W|WU|V|F|D)load [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) ++ ++(MOV(B|H|W|V|F|D)store [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) ++ && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) => ++ (MOV(B|H|W|V|F|D)store [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) ++ ++(MOV(B|H|W|V)storezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) ++ && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) => ++ (MOV(B|H|W|V)storezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) + + (LoweredAtomicStore(32|64) ptr (MOVVconst [0]) mem) => (LoweredAtomicStorezero(32|64) ptr mem) + (LoweredAtomicAdd32 ptr (MOVVconst [c]) mem) && is32Bit(c) => (LoweredAtomicAddconst32 [int32(c)] ptr mem) +diff --git a/src/cmd/compile/internal/ssa/regalloc.go b/src/cmd/compile/internal/ssa/regalloc.go +index c4d6e48cad..71fedd52cf 100644 +--- a/src/cmd/compile/internal/ssa/regalloc.go ++++ b/src/cmd/compile/internal/ssa/regalloc.go +@@ -672,6 +672,8 @@ func (s *regAllocState) init(f *Func) { + s.allocatable &^= 1 << 9 // R9 + case "arm64": + // nothing to do ++ case "loong64": // R2 (aka TP) already reserved. ++ // nothing to do + case "ppc64le": // R2 already reserved. + // nothing to do + case "riscv64": // X3 (aka GP) and X4 (aka TP) already reserved. +diff --git a/src/cmd/compile/internal/ssa/rewriteLOONG64.go b/src/cmd/compile/internal/ssa/rewriteLOONG64.go +index e88b74cb22..757524bdbb 100644 +--- a/src/cmd/compile/internal/ssa/rewriteLOONG64.go ++++ b/src/cmd/compile/internal/ssa/rewriteLOONG64.go +@@ -1724,8 +1724,10 @@ func rewriteValueLOONG64_OpLOONG64MASKNEZ(v *Value) bool { + func rewriteValueLOONG64_OpLOONG64MOVBUload(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] ++ b := v.Block ++ config := b.Func.Config + // match: (MOVBUload [off1] {sym} (ADDVconst [off2] ptr) mem) +- // cond: is32Bit(int64(off1)+off2) ++ // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) + // result: (MOVBUload [off1+int32(off2)] {sym} ptr mem) + for { + off1 := auxIntToInt32(v.AuxInt) +@@ -1736,7 +1738,7 @@ func rewriteValueLOONG64_OpLOONG64MOVBUload(v *Value) bool { + off2 := auxIntToInt64(v_0.AuxInt) + ptr := v_0.Args[0] + mem := v_1 +- if !(is32Bit(int64(off1) + off2)) { ++ if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { + break + } + v.reset(OpLOONG64MOVBUload) +@@ -1746,7 +1748,7 @@ func rewriteValueLOONG64_OpLOONG64MOVBUload(v *Value) bool { + return true + } + // match: (MOVBUload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) +- // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) ++ // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) + // result: (MOVBUload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) + for { + off1 := auxIntToInt32(v.AuxInt) +@@ -1758,7 +1760,7 @@ func rewriteValueLOONG64_OpLOONG64MOVBUload(v *Value) bool { + sym2 := auxToSym(v_0.Aux) + ptr := v_0.Args[0] + mem := v_1 +- if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) { ++ if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { + break + } + v.reset(OpLOONG64MOVBUload) +@@ -1809,8 +1811,10 @@ func rewriteValueLOONG64_OpLOONG64MOVBUreg(v *Value) bool { + func rewriteValueLOONG64_OpLOONG64MOVBload(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] ++ b := v.Block ++ config := b.Func.Config + // match: (MOVBload [off1] {sym} (ADDVconst [off2] ptr) mem) +- // cond: is32Bit(int64(off1)+off2) ++ // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) + // result: (MOVBload [off1+int32(off2)] {sym} ptr mem) + for { + off1 := auxIntToInt32(v.AuxInt) +@@ -1821,7 +1825,7 @@ func rewriteValueLOONG64_OpLOONG64MOVBload(v *Value) bool { + off2 := auxIntToInt64(v_0.AuxInt) + ptr := v_0.Args[0] + mem := v_1 +- if !(is32Bit(int64(off1) + off2)) { ++ if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { + break + } + v.reset(OpLOONG64MOVBload) +@@ -1831,7 +1835,7 @@ func rewriteValueLOONG64_OpLOONG64MOVBload(v *Value) bool { + return true + } + // match: (MOVBload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) +- // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) ++ // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) + // result: (MOVBload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) + for { + off1 := auxIntToInt32(v.AuxInt) +@@ -1843,7 +1847,7 @@ func rewriteValueLOONG64_OpLOONG64MOVBload(v *Value) bool { + sym2 := auxToSym(v_0.Aux) + ptr := v_0.Args[0] + mem := v_1 +- if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) { ++ if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { + break + } + v.reset(OpLOONG64MOVBload) +@@ -1895,8 +1899,10 @@ func rewriteValueLOONG64_OpLOONG64MOVBstore(v *Value) bool { + v_2 := v.Args[2] + v_1 := v.Args[1] + v_0 := v.Args[0] ++ b := v.Block ++ config := b.Func.Config + // match: (MOVBstore [off1] {sym} (ADDVconst [off2] ptr) val mem) +- // cond: is32Bit(int64(off1)+off2) ++ // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) + // result: (MOVBstore [off1+int32(off2)] {sym} ptr val mem) + for { + off1 := auxIntToInt32(v.AuxInt) +@@ -1908,7 +1914,7 @@ func rewriteValueLOONG64_OpLOONG64MOVBstore(v *Value) bool { + ptr := v_0.Args[0] + val := v_1 + mem := v_2 +- if !(is32Bit(int64(off1) + off2)) { ++ if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { + break + } + v.reset(OpLOONG64MOVBstore) +@@ -1918,7 +1924,7 @@ func rewriteValueLOONG64_OpLOONG64MOVBstore(v *Value) bool { + return true + } + // match: (MOVBstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) +- // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) ++ // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) + // result: (MOVBstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) + for { + off1 := auxIntToInt32(v.AuxInt) +@@ -1931,7 +1937,7 @@ func rewriteValueLOONG64_OpLOONG64MOVBstore(v *Value) bool { + ptr := v_0.Args[0] + val := v_1 + mem := v_2 +- if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) { ++ if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { + break + } + v.reset(OpLOONG64MOVBstore) +@@ -2047,8 +2053,10 @@ func rewriteValueLOONG64_OpLOONG64MOVBstore(v *Value) bool { + func rewriteValueLOONG64_OpLOONG64MOVBstorezero(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] ++ b := v.Block ++ config := b.Func.Config + // match: (MOVBstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) +- // cond: is32Bit(int64(off1)+off2) ++ // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) + // result: (MOVBstorezero [off1+int32(off2)] {sym} ptr mem) + for { + off1 := auxIntToInt32(v.AuxInt) +@@ -2059,7 +2067,7 @@ func rewriteValueLOONG64_OpLOONG64MOVBstorezero(v *Value) bool { + off2 := auxIntToInt64(v_0.AuxInt) + ptr := v_0.Args[0] + mem := v_1 +- if !(is32Bit(int64(off1) + off2)) { ++ if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { + break + } + v.reset(OpLOONG64MOVBstorezero) +@@ -2069,7 +2077,7 @@ func rewriteValueLOONG64_OpLOONG64MOVBstorezero(v *Value) bool { + return true + } + // match: (MOVBstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) +- // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) ++ // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) + // result: (MOVBstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) + for { + off1 := auxIntToInt32(v.AuxInt) +@@ -2081,7 +2089,7 @@ func rewriteValueLOONG64_OpLOONG64MOVBstorezero(v *Value) bool { + sym2 := auxToSym(v_0.Aux) + ptr := v_0.Args[0] + mem := v_1 +- if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) { ++ if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { + break + } + v.reset(OpLOONG64MOVBstorezero) +@@ -2095,8 +2103,10 @@ func rewriteValueLOONG64_OpLOONG64MOVBstorezero(v *Value) bool { + func rewriteValueLOONG64_OpLOONG64MOVDload(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] ++ b := v.Block ++ config := b.Func.Config + // match: (MOVDload [off1] {sym} (ADDVconst [off2] ptr) mem) +- // cond: is32Bit(int64(off1)+off2) ++ // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) + // result: (MOVDload [off1+int32(off2)] {sym} ptr mem) + for { + off1 := auxIntToInt32(v.AuxInt) +@@ -2107,7 +2117,7 @@ func rewriteValueLOONG64_OpLOONG64MOVDload(v *Value) bool { + off2 := auxIntToInt64(v_0.AuxInt) + ptr := v_0.Args[0] + mem := v_1 +- if !(is32Bit(int64(off1) + off2)) { ++ if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { + break + } + v.reset(OpLOONG64MOVDload) +@@ -2117,7 +2127,7 @@ func rewriteValueLOONG64_OpLOONG64MOVDload(v *Value) bool { + return true + } + // match: (MOVDload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) +- // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) ++ // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) + // result: (MOVDload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) + for { + off1 := auxIntToInt32(v.AuxInt) +@@ -2129,7 +2139,7 @@ func rewriteValueLOONG64_OpLOONG64MOVDload(v *Value) bool { + sym2 := auxToSym(v_0.Aux) + ptr := v_0.Args[0] + mem := v_1 +- if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) { ++ if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { + break + } + v.reset(OpLOONG64MOVDload) +@@ -2144,8 +2154,10 @@ func rewriteValueLOONG64_OpLOONG64MOVDstore(v *Value) bool { + v_2 := v.Args[2] + v_1 := v.Args[1] + v_0 := v.Args[0] ++ b := v.Block ++ config := b.Func.Config + // match: (MOVDstore [off1] {sym} (ADDVconst [off2] ptr) val mem) +- // cond: is32Bit(int64(off1)+off2) ++ // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) + // result: (MOVDstore [off1+int32(off2)] {sym} ptr val mem) + for { + off1 := auxIntToInt32(v.AuxInt) +@@ -2157,7 +2169,7 @@ func rewriteValueLOONG64_OpLOONG64MOVDstore(v *Value) bool { + ptr := v_0.Args[0] + val := v_1 + mem := v_2 +- if !(is32Bit(int64(off1) + off2)) { ++ if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { + break + } + v.reset(OpLOONG64MOVDstore) +@@ -2167,7 +2179,7 @@ func rewriteValueLOONG64_OpLOONG64MOVDstore(v *Value) bool { + return true + } + // match: (MOVDstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) +- // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) ++ // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) + // result: (MOVDstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) + for { + off1 := auxIntToInt32(v.AuxInt) +@@ -2180,7 +2192,7 @@ func rewriteValueLOONG64_OpLOONG64MOVDstore(v *Value) bool { + ptr := v_0.Args[0] + val := v_1 + mem := v_2 +- if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) { ++ if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { + break + } + v.reset(OpLOONG64MOVDstore) +@@ -2194,8 +2206,10 @@ func rewriteValueLOONG64_OpLOONG64MOVDstore(v *Value) bool { + func rewriteValueLOONG64_OpLOONG64MOVFload(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] ++ b := v.Block ++ config := b.Func.Config + // match: (MOVFload [off1] {sym} (ADDVconst [off2] ptr) mem) +- // cond: is32Bit(int64(off1)+off2) ++ // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) + // result: (MOVFload [off1+int32(off2)] {sym} ptr mem) + for { + off1 := auxIntToInt32(v.AuxInt) +@@ -2206,7 +2220,7 @@ func rewriteValueLOONG64_OpLOONG64MOVFload(v *Value) bool { + off2 := auxIntToInt64(v_0.AuxInt) + ptr := v_0.Args[0] + mem := v_1 +- if !(is32Bit(int64(off1) + off2)) { ++ if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { + break + } + v.reset(OpLOONG64MOVFload) +@@ -2216,7 +2230,7 @@ func rewriteValueLOONG64_OpLOONG64MOVFload(v *Value) bool { + return true + } + // match: (MOVFload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) +- // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) ++ // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) + // result: (MOVFload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) + for { + off1 := auxIntToInt32(v.AuxInt) +@@ -2228,7 +2242,7 @@ func rewriteValueLOONG64_OpLOONG64MOVFload(v *Value) bool { + sym2 := auxToSym(v_0.Aux) + ptr := v_0.Args[0] + mem := v_1 +- if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) { ++ if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { + break + } + v.reset(OpLOONG64MOVFload) +@@ -2243,8 +2257,10 @@ func rewriteValueLOONG64_OpLOONG64MOVFstore(v *Value) bool { + v_2 := v.Args[2] + v_1 := v.Args[1] + v_0 := v.Args[0] ++ b := v.Block ++ config := b.Func.Config + // match: (MOVFstore [off1] {sym} (ADDVconst [off2] ptr) val mem) +- // cond: is32Bit(int64(off1)+off2) ++ // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) + // result: (MOVFstore [off1+int32(off2)] {sym} ptr val mem) + for { + off1 := auxIntToInt32(v.AuxInt) +@@ -2256,7 +2272,7 @@ func rewriteValueLOONG64_OpLOONG64MOVFstore(v *Value) bool { + ptr := v_0.Args[0] + val := v_1 + mem := v_2 +- if !(is32Bit(int64(off1) + off2)) { ++ if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { + break + } + v.reset(OpLOONG64MOVFstore) +@@ -2266,7 +2282,7 @@ func rewriteValueLOONG64_OpLOONG64MOVFstore(v *Value) bool { + return true + } + // match: (MOVFstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) +- // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) ++ // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) + // result: (MOVFstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) + for { + off1 := auxIntToInt32(v.AuxInt) +@@ -2279,7 +2295,7 @@ func rewriteValueLOONG64_OpLOONG64MOVFstore(v *Value) bool { + ptr := v_0.Args[0] + val := v_1 + mem := v_2 +- if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) { ++ if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { + break + } + v.reset(OpLOONG64MOVFstore) +@@ -2293,8 +2309,10 @@ func rewriteValueLOONG64_OpLOONG64MOVFstore(v *Value) bool { + func rewriteValueLOONG64_OpLOONG64MOVHUload(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] ++ b := v.Block ++ config := b.Func.Config + // match: (MOVHUload [off1] {sym} (ADDVconst [off2] ptr) mem) +- // cond: is32Bit(int64(off1)+off2) ++ // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) + // result: (MOVHUload [off1+int32(off2)] {sym} ptr mem) + for { + off1 := auxIntToInt32(v.AuxInt) +@@ -2305,7 +2323,7 @@ func rewriteValueLOONG64_OpLOONG64MOVHUload(v *Value) bool { + off2 := auxIntToInt64(v_0.AuxInt) + ptr := v_0.Args[0] + mem := v_1 +- if !(is32Bit(int64(off1) + off2)) { ++ if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { + break + } + v.reset(OpLOONG64MOVHUload) +@@ -2315,7 +2333,7 @@ func rewriteValueLOONG64_OpLOONG64MOVHUload(v *Value) bool { + return true + } + // match: (MOVHUload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) +- // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) ++ // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) + // result: (MOVHUload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) + for { + off1 := auxIntToInt32(v.AuxInt) +@@ -2327,7 +2345,7 @@ func rewriteValueLOONG64_OpLOONG64MOVHUload(v *Value) bool { + sym2 := auxToSym(v_0.Aux) + ptr := v_0.Args[0] + mem := v_1 +- if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) { ++ if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { + break + } + v.reset(OpLOONG64MOVHUload) +@@ -2400,8 +2418,10 @@ func rewriteValueLOONG64_OpLOONG64MOVHUreg(v *Value) bool { + func rewriteValueLOONG64_OpLOONG64MOVHload(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] ++ b := v.Block ++ config := b.Func.Config + // match: (MOVHload [off1] {sym} (ADDVconst [off2] ptr) mem) +- // cond: is32Bit(int64(off1)+off2) ++ // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) + // result: (MOVHload [off1+int32(off2)] {sym} ptr mem) + for { + off1 := auxIntToInt32(v.AuxInt) +@@ -2412,7 +2432,7 @@ func rewriteValueLOONG64_OpLOONG64MOVHload(v *Value) bool { + off2 := auxIntToInt64(v_0.AuxInt) + ptr := v_0.Args[0] + mem := v_1 +- if !(is32Bit(int64(off1) + off2)) { ++ if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { + break + } + v.reset(OpLOONG64MOVHload) +@@ -2422,7 +2442,7 @@ func rewriteValueLOONG64_OpLOONG64MOVHload(v *Value) bool { + return true + } + // match: (MOVHload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) +- // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) ++ // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) + // result: (MOVHload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) + for { + off1 := auxIntToInt32(v.AuxInt) +@@ -2434,7 +2454,7 @@ func rewriteValueLOONG64_OpLOONG64MOVHload(v *Value) bool { + sym2 := auxToSym(v_0.Aux) + ptr := v_0.Args[0] + mem := v_1 +- if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) { ++ if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { + break + } + v.reset(OpLOONG64MOVHload) +@@ -2530,8 +2550,10 @@ func rewriteValueLOONG64_OpLOONG64MOVHstore(v *Value) bool { + v_2 := v.Args[2] + v_1 := v.Args[1] + v_0 := v.Args[0] ++ b := v.Block ++ config := b.Func.Config + // match: (MOVHstore [off1] {sym} (ADDVconst [off2] ptr) val mem) +- // cond: is32Bit(int64(off1)+off2) ++ // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) + // result: (MOVHstore [off1+int32(off2)] {sym} ptr val mem) + for { + off1 := auxIntToInt32(v.AuxInt) +@@ -2543,7 +2565,7 @@ func rewriteValueLOONG64_OpLOONG64MOVHstore(v *Value) bool { + ptr := v_0.Args[0] + val := v_1 + mem := v_2 +- if !(is32Bit(int64(off1) + off2)) { ++ if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { + break + } + v.reset(OpLOONG64MOVHstore) +@@ -2553,7 +2575,7 @@ func rewriteValueLOONG64_OpLOONG64MOVHstore(v *Value) bool { + return true + } + // match: (MOVHstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) +- // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) ++ // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) + // result: (MOVHstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) + for { + off1 := auxIntToInt32(v.AuxInt) +@@ -2566,7 +2588,7 @@ func rewriteValueLOONG64_OpLOONG64MOVHstore(v *Value) bool { + ptr := v_0.Args[0] + val := v_1 + mem := v_2 +- if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) { ++ if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { + break + } + v.reset(OpLOONG64MOVHstore) +@@ -2648,8 +2670,10 @@ func rewriteValueLOONG64_OpLOONG64MOVHstore(v *Value) bool { + func rewriteValueLOONG64_OpLOONG64MOVHstorezero(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] ++ b := v.Block ++ config := b.Func.Config + // match: (MOVHstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) +- // cond: is32Bit(int64(off1)+off2) ++ // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) + // result: (MOVHstorezero [off1+int32(off2)] {sym} ptr mem) + for { + off1 := auxIntToInt32(v.AuxInt) +@@ -2660,7 +2684,7 @@ func rewriteValueLOONG64_OpLOONG64MOVHstorezero(v *Value) bool { + off2 := auxIntToInt64(v_0.AuxInt) + ptr := v_0.Args[0] + mem := v_1 +- if !(is32Bit(int64(off1) + off2)) { ++ if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { + break + } + v.reset(OpLOONG64MOVHstorezero) +@@ -2670,7 +2694,7 @@ func rewriteValueLOONG64_OpLOONG64MOVHstorezero(v *Value) bool { + return true + } + // match: (MOVHstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) +- // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) ++ // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) + // result: (MOVHstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) + for { + off1 := auxIntToInt32(v.AuxInt) +@@ -2682,7 +2706,7 @@ func rewriteValueLOONG64_OpLOONG64MOVHstorezero(v *Value) bool { + sym2 := auxToSym(v_0.Aux) + ptr := v_0.Args[0] + mem := v_1 +- if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) { ++ if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { + break + } + v.reset(OpLOONG64MOVHstorezero) +@@ -2696,8 +2720,10 @@ func rewriteValueLOONG64_OpLOONG64MOVHstorezero(v *Value) bool { + func rewriteValueLOONG64_OpLOONG64MOVVload(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] ++ b := v.Block ++ config := b.Func.Config + // match: (MOVVload [off1] {sym} (ADDVconst [off2] ptr) mem) +- // cond: is32Bit(int64(off1)+off2) ++ // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) + // result: (MOVVload [off1+int32(off2)] {sym} ptr mem) + for { + off1 := auxIntToInt32(v.AuxInt) +@@ -2708,7 +2734,7 @@ func rewriteValueLOONG64_OpLOONG64MOVVload(v *Value) bool { + off2 := auxIntToInt64(v_0.AuxInt) + ptr := v_0.Args[0] + mem := v_1 +- if !(is32Bit(int64(off1) + off2)) { ++ if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { + break + } + v.reset(OpLOONG64MOVVload) +@@ -2718,7 +2744,7 @@ func rewriteValueLOONG64_OpLOONG64MOVVload(v *Value) bool { + return true + } + // match: (MOVVload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) +- // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) ++ // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) + // result: (MOVVload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) + for { + off1 := auxIntToInt32(v.AuxInt) +@@ -2730,7 +2756,7 @@ func rewriteValueLOONG64_OpLOONG64MOVVload(v *Value) bool { + sym2 := auxToSym(v_0.Aux) + ptr := v_0.Args[0] + mem := v_1 +- if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) { ++ if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { + break + } + v.reset(OpLOONG64MOVVload) +@@ -2772,8 +2798,10 @@ func rewriteValueLOONG64_OpLOONG64MOVVstore(v *Value) bool { + v_2 := v.Args[2] + v_1 := v.Args[1] + v_0 := v.Args[0] ++ b := v.Block ++ config := b.Func.Config + // match: (MOVVstore [off1] {sym} (ADDVconst [off2] ptr) val mem) +- // cond: is32Bit(int64(off1)+off2) ++ // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) + // result: (MOVVstore [off1+int32(off2)] {sym} ptr val mem) + for { + off1 := auxIntToInt32(v.AuxInt) +@@ -2785,7 +2813,7 @@ func rewriteValueLOONG64_OpLOONG64MOVVstore(v *Value) bool { + ptr := v_0.Args[0] + val := v_1 + mem := v_2 +- if !(is32Bit(int64(off1) + off2)) { ++ if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { + break + } + v.reset(OpLOONG64MOVVstore) +@@ -2795,7 +2823,7 @@ func rewriteValueLOONG64_OpLOONG64MOVVstore(v *Value) bool { + return true + } + // match: (MOVVstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) +- // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) ++ // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) + // result: (MOVVstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) + for { + off1 := auxIntToInt32(v.AuxInt) +@@ -2808,7 +2836,7 @@ func rewriteValueLOONG64_OpLOONG64MOVVstore(v *Value) bool { + ptr := v_0.Args[0] + val := v_1 + mem := v_2 +- if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) { ++ if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { + break + } + v.reset(OpLOONG64MOVVstore) +@@ -2822,8 +2850,10 @@ func rewriteValueLOONG64_OpLOONG64MOVVstore(v *Value) bool { + func rewriteValueLOONG64_OpLOONG64MOVVstorezero(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] ++ b := v.Block ++ config := b.Func.Config + // match: (MOVVstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) +- // cond: is32Bit(int64(off1)+off2) ++ // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) + // result: (MOVVstorezero [off1+int32(off2)] {sym} ptr mem) + for { + off1 := auxIntToInt32(v.AuxInt) +@@ -2834,7 +2864,7 @@ func rewriteValueLOONG64_OpLOONG64MOVVstorezero(v *Value) bool { + off2 := auxIntToInt64(v_0.AuxInt) + ptr := v_0.Args[0] + mem := v_1 +- if !(is32Bit(int64(off1) + off2)) { ++ if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { + break + } + v.reset(OpLOONG64MOVVstorezero) +@@ -2844,7 +2874,7 @@ func rewriteValueLOONG64_OpLOONG64MOVVstorezero(v *Value) bool { + return true + } + // match: (MOVVstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) +- // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) ++ // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) + // result: (MOVVstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) + for { + off1 := auxIntToInt32(v.AuxInt) +@@ -2856,7 +2886,7 @@ func rewriteValueLOONG64_OpLOONG64MOVVstorezero(v *Value) bool { + sym2 := auxToSym(v_0.Aux) + ptr := v_0.Args[0] + mem := v_1 +- if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) { ++ if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { + break + } + v.reset(OpLOONG64MOVVstorezero) +@@ -2870,8 +2900,10 @@ func rewriteValueLOONG64_OpLOONG64MOVVstorezero(v *Value) bool { + func rewriteValueLOONG64_OpLOONG64MOVWUload(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] ++ b := v.Block ++ config := b.Func.Config + // match: (MOVWUload [off1] {sym} (ADDVconst [off2] ptr) mem) +- // cond: is32Bit(int64(off1)+off2) ++ // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) + // result: (MOVWUload [off1+int32(off2)] {sym} ptr mem) + for { + off1 := auxIntToInt32(v.AuxInt) +@@ -2882,7 +2914,7 @@ func rewriteValueLOONG64_OpLOONG64MOVWUload(v *Value) bool { + off2 := auxIntToInt64(v_0.AuxInt) + ptr := v_0.Args[0] + mem := v_1 +- if !(is32Bit(int64(off1) + off2)) { ++ if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { + break + } + v.reset(OpLOONG64MOVWUload) +@@ -2892,7 +2924,7 @@ func rewriteValueLOONG64_OpLOONG64MOVWUload(v *Value) bool { + return true + } + // match: (MOVWUload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) +- // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) ++ // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) + // result: (MOVWUload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) + for { + off1 := auxIntToInt32(v.AuxInt) +@@ -2904,7 +2936,7 @@ func rewriteValueLOONG64_OpLOONG64MOVWUload(v *Value) bool { + sym2 := auxToSym(v_0.Aux) + ptr := v_0.Args[0] + mem := v_1 +- if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) { ++ if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { + break + } + v.reset(OpLOONG64MOVWUload) +@@ -2999,8 +3031,10 @@ func rewriteValueLOONG64_OpLOONG64MOVWUreg(v *Value) bool { + func rewriteValueLOONG64_OpLOONG64MOVWload(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] ++ b := v.Block ++ config := b.Func.Config + // match: (MOVWload [off1] {sym} (ADDVconst [off2] ptr) mem) +- // cond: is32Bit(int64(off1)+off2) ++ // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) + // result: (MOVWload [off1+int32(off2)] {sym} ptr mem) + for { + off1 := auxIntToInt32(v.AuxInt) +@@ -3011,7 +3045,7 @@ func rewriteValueLOONG64_OpLOONG64MOVWload(v *Value) bool { + off2 := auxIntToInt64(v_0.AuxInt) + ptr := v_0.Args[0] + mem := v_1 +- if !(is32Bit(int64(off1) + off2)) { ++ if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { + break + } + v.reset(OpLOONG64MOVWload) +@@ -3021,7 +3055,7 @@ func rewriteValueLOONG64_OpLOONG64MOVWload(v *Value) bool { + return true + } + // match: (MOVWload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) +- // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) ++ // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) + // result: (MOVWload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) + for { + off1 := auxIntToInt32(v.AuxInt) +@@ -3033,7 +3067,7 @@ func rewriteValueLOONG64_OpLOONG64MOVWload(v *Value) bool { + sym2 := auxToSym(v_0.Aux) + ptr := v_0.Args[0] + mem := v_1 +- if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) { ++ if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { + break + } + v.reset(OpLOONG64MOVWload) +@@ -3162,8 +3196,10 @@ func rewriteValueLOONG64_OpLOONG64MOVWstore(v *Value) bool { + v_2 := v.Args[2] + v_1 := v.Args[1] + v_0 := v.Args[0] ++ b := v.Block ++ config := b.Func.Config + // match: (MOVWstore [off1] {sym} (ADDVconst [off2] ptr) val mem) +- // cond: is32Bit(int64(off1)+off2) ++ // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) + // result: (MOVWstore [off1+int32(off2)] {sym} ptr val mem) + for { + off1 := auxIntToInt32(v.AuxInt) +@@ -3175,7 +3211,7 @@ func rewriteValueLOONG64_OpLOONG64MOVWstore(v *Value) bool { + ptr := v_0.Args[0] + val := v_1 + mem := v_2 +- if !(is32Bit(int64(off1) + off2)) { ++ if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { + break + } + v.reset(OpLOONG64MOVWstore) +@@ -3185,7 +3221,7 @@ func rewriteValueLOONG64_OpLOONG64MOVWstore(v *Value) bool { + return true + } + // match: (MOVWstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) +- // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) ++ // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) + // result: (MOVWstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) + for { + off1 := auxIntToInt32(v.AuxInt) +@@ -3198,7 +3234,7 @@ func rewriteValueLOONG64_OpLOONG64MOVWstore(v *Value) bool { + ptr := v_0.Args[0] + val := v_1 + mem := v_2 +- if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) { ++ if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { + break + } + v.reset(OpLOONG64MOVWstore) +@@ -3246,8 +3282,10 @@ func rewriteValueLOONG64_OpLOONG64MOVWstore(v *Value) bool { + func rewriteValueLOONG64_OpLOONG64MOVWstorezero(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] ++ b := v.Block ++ config := b.Func.Config + // match: (MOVWstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) +- // cond: is32Bit(int64(off1)+off2) ++ // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) + // result: (MOVWstorezero [off1+int32(off2)] {sym} ptr mem) + for { + off1 := auxIntToInt32(v.AuxInt) +@@ -3258,7 +3296,7 @@ func rewriteValueLOONG64_OpLOONG64MOVWstorezero(v *Value) bool { + off2 := auxIntToInt64(v_0.AuxInt) + ptr := v_0.Args[0] + mem := v_1 +- if !(is32Bit(int64(off1) + off2)) { ++ if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { + break + } + v.reset(OpLOONG64MOVWstorezero) +@@ -3268,7 +3306,7 @@ func rewriteValueLOONG64_OpLOONG64MOVWstorezero(v *Value) bool { + return true + } + // match: (MOVWstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) +- // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) ++ // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) + // result: (MOVWstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) + for { + off1 := auxIntToInt32(v.AuxInt) +@@ -3280,7 +3318,7 @@ func rewriteValueLOONG64_OpLOONG64MOVWstorezero(v *Value) bool { + sym2 := auxToSym(v_0.Aux) + ptr := v_0.Args[0] + mem := v_1 +- if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) { ++ if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) { + break + } + v.reset(OpLOONG64MOVWstorezero) +diff --git a/src/cmd/dist/test.go b/src/cmd/dist/test.go +index 36a20e8b2a..864060cbb2 100644 +--- a/src/cmd/dist/test.go ++++ b/src/cmd/dist/test.go +@@ -1613,14 +1613,14 @@ func buildModeSupported(compiler, buildmode, goos, goarch string) bool { + + case "shared": + switch platform { +- case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x": ++ case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/loong64", "linux/ppc64le", "linux/s390x": + return true + } + return false + + case "plugin": + switch platform { +- case "linux/amd64", "linux/arm", "linux/arm64", "linux/386", "linux/s390x", "linux/ppc64le", ++ case "linux/amd64", "linux/arm", "linux/arm64", "linux/386", "linux/loong64", "linux/s390x", "linux/ppc64le", + "android/amd64", "android/386", + "darwin/amd64", "darwin/arm64", + "freebsd/amd64": +diff --git a/src/cmd/internal/obj/loong64/a.out.go b/src/cmd/internal/obj/loong64/a.out.go +index 99a7da388f..9527e99b56 100644 +--- a/src/cmd/internal/obj/loong64/a.out.go ++++ b/src/cmd/internal/obj/loong64/a.out.go +@@ -227,6 +227,7 @@ const ( + C_ADDR + C_TLS_LE + C_TLS_IE ++ C_GOTADDR + C_TEXTSIZE + + C_NCLASS // must be the last +diff --git a/src/cmd/internal/obj/loong64/asm.go b/src/cmd/internal/obj/loong64/asm.go +index 0ab0caafae..c8d00413a0 100644 +--- a/src/cmd/internal/obj/loong64/asm.go ++++ b/src/cmd/internal/obj/loong64/asm.go +@@ -349,6 +349,8 @@ var optab = []Optab{ + {AWORD, C_LCON, C_NONE, C_NONE, C_NONE, C_NONE, 40, 4, 0, 0}, + {AWORD, C_DCON, C_NONE, C_NONE, C_NONE, C_NONE, 61, 4, 0, 0}, + ++ {AMOVV, C_GOTADDR, C_NONE, C_NONE, C_REG, C_NONE, 65, 8, 0, 0}, ++ + {ATEQ, C_SCON, C_REG, C_NONE, C_REG, C_NONE, 15, 8, 0, 0}, + {ATEQ, C_SCON, C_NONE, C_NONE, C_REG, C_NONE, 15, 8, 0, 0}, + +@@ -676,6 +678,9 @@ func (c *ctxt0) aclass(a *obj.Addr) int { + return C_SOREG + } + return C_LOREG ++ ++ case obj.NAME_GOTREF: ++ return C_GOTADDR + } + + return C_GOK +@@ -1776,6 +1781,22 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) { + case 64: // movv c_reg, c_fcc0 ==> movgr2cf cd, rj + a := OP_TEN(8, 1334) + o1 = OP_RR(a, uint32(p.From.Reg), uint32(p.To.Reg)) ++ ++ case 65: // mov sym@GOT, r ==> pcalau12i + ld.d ++ o1 = OP_IR(c.opir(APCALAU12I), uint32(0), uint32(p.To.Reg)) ++ rel := obj.Addrel(c.cursym) ++ rel.Off = int32(c.pc) ++ rel.Siz = 4 ++ rel.Sym = p.From.Sym ++ rel.Type = objabi.R_LOONG64_GOTPCREL_HI ++ rel.Add = 0x0 ++ o2 = OP_12IRR(c.opirr(-p.As), uint32(0), uint32(p.To.Reg), uint32(p.To.Reg)) ++ rel2 := obj.Addrel(c.cursym) ++ rel2.Off = int32(c.pc + 4) ++ rel2.Siz = 4 ++ rel2.Sym = p.From.Sym ++ rel2.Type = objabi.R_LOONG64_GOT_LO ++ rel2.Add = 0x0 + } + + out[0] = o1 +diff --git a/src/cmd/internal/obj/loong64/cnames.go b/src/cmd/internal/obj/loong64/cnames.go +index 8b8af6ba31..94b1b54c93 100644 +--- a/src/cmd/internal/obj/loong64/cnames.go ++++ b/src/cmd/internal/obj/loong64/cnames.go +@@ -39,6 +39,7 @@ var cnames0 = []string{ + "ADDR", + "TLS_LE", + "TLS_IE", ++ "GOTADDR", + "TEXTSIZE", + "NCLASS", + } +diff --git a/src/cmd/internal/obj/loong64/obj.go b/src/cmd/internal/obj/loong64/obj.go +index 1eedd46c69..38ab66b819 100644 +--- a/src/cmd/internal/obj/loong64/obj.go ++++ b/src/cmd/internal/obj/loong64/obj.go +@@ -6,6 +6,7 @@ package loong64 + + import ( + "cmd/internal/obj" ++ "cmd/internal/objabi" + "cmd/internal/sys" + "internal/abi" + "log" +@@ -84,6 +85,128 @@ func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) { + p.As = AADDVU + } + } ++ ++ if ctxt.Flag_dynlink { ++ rewriteToUseGot(ctxt, p, newprog) ++ } ++} ++ ++func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) { ++ // ADUFFxxx $offset ++ // becomes ++ // MOVV runtime.duffxxx@GOT, REGTMP ++ // ADD $offset, REGTMP ++ // JAL REGTMP ++ if p.As == obj.ADUFFCOPY || p.As == obj.ADUFFZERO { ++ var sym *obj.LSym ++ if p.As == obj.ADUFFZERO { ++ sym = ctxt.Lookup("runtime.duffzero") ++ } else { ++ sym = ctxt.Lookup("runtime.duffcopy") ++ } ++ offset := p.To.Offset ++ p.As = AMOVV ++ p.From.Type = obj.TYPE_MEM ++ p.From.Sym = sym ++ p.From.Name = obj.NAME_GOTREF ++ p.To.Type = obj.TYPE_REG ++ p.To.Reg = REGTMP ++ p.To.Name = obj.NAME_NONE ++ p.To.Offset = 0 ++ p.To.Sym = nil ++ p1 := obj.Appendp(p, newprog) ++ p1.As = AADDV ++ p1.From.Type = obj.TYPE_CONST ++ p1.From.Offset = offset ++ p1.To.Type = obj.TYPE_REG ++ p1.To.Reg = REGTMP ++ p2 := obj.Appendp(p1, newprog) ++ p2.As = obj.ACALL ++ p2.To.Type = obj.TYPE_MEM ++ p2.To.Reg = REGTMP ++ return ++ } ++ ++ // We only care about global data: NAME_EXTERN means a global symbol in the ++ // Go sense, and p.Sym.Local is true for a few internally defined symbols. ++ if p.From.Type == obj.TYPE_ADDR && p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() { ++ // MOVV $sym, Rx becomes MOVV sym@GOT, Rx ++ // MOVV $sym+, Rx becomes MOVV sym@GOT, Rx; ADD , Rx ++ if p.As != AMOVV { ++ ctxt.Diag("do not know how to handle TYPE_ADDR in %v with -shared", p) ++ } ++ if p.To.Type != obj.TYPE_REG { ++ ctxt.Diag("do not know how to handle LEAQ-type insn to non-register in %v with -shared", p) ++ } ++ p.From.Type = obj.TYPE_MEM ++ p.From.Name = obj.NAME_GOTREF ++ if p.From.Offset != 0 { ++ q := obj.Appendp(p, newprog) ++ q.As = AADDV ++ q.From.Type = obj.TYPE_CONST ++ q.From.Offset = p.From.Offset ++ q.To = p.To ++ p.From.Offset = 0 ++ } ++ return ++ } ++ ++ if p.GetFrom3() != nil && p.GetFrom3().Name == obj.NAME_EXTERN { ++ ctxt.Diag("don't know how to handle %v with -shared", p) ++ } ++ ++ // MOVx sym, Ry becomes MOVV sym@GOT, REGTMP; MOVx (REGTMP), Ry ++ // MOVx Ry, sym becomes MOVV sym@GOT, REGTMP; MOVx Ry, (REGTMP) ++ // An addition may be inserted between the two MOVs if there is an offset. ++ var source *obj.Addr ++ if p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() { ++ if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() { ++ ctxt.Diag("cannot handle NAME_EXTERN on both sides in %v with -shared", p) ++ } ++ source = &p.From ++ } else if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() { ++ source = &p.To ++ } else { ++ return ++ } ++ ++ if p.As == obj.ATEXT || p.As == obj.AFUNCDATA || p.As == obj.ACALL || p.As == obj.ARET || p.As == obj.AJMP { ++ return ++ } ++ ++ if source.Sym.Type == objabi.STLSBSS { ++ return ++ } ++ ++ if source.Type != obj.TYPE_MEM { ++ ctxt.Diag("don't know how to handle %v with -shared", p) ++ } ++ ++ p1 := obj.Appendp(p, newprog) ++ p1.As = AMOVV ++ p1.From.Type = obj.TYPE_MEM ++ p1.From.Sym = source.Sym ++ p1.From.Name = obj.NAME_GOTREF ++ p1.To.Type = obj.TYPE_REG ++ p1.To.Reg = REGTMP ++ ++ p2 := obj.Appendp(p1, newprog) ++ p2.As = p.As ++ p2.From = p.From ++ p2.To = p.To ++ if p.From.Name == obj.NAME_EXTERN { ++ p2.From.Reg = REGTMP ++ p2.From.Name = obj.NAME_NONE ++ p2.From.Sym = nil ++ } else if p.To.Name == obj.NAME_EXTERN { ++ p2.To.Reg = REGTMP ++ p2.To.Name = obj.NAME_NONE ++ p2.To.Sym = nil ++ } else { ++ return ++ } ++ ++ obj.Nopout(p) + } + + func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { +diff --git a/src/cmd/internal/objabi/reloctype.go b/src/cmd/internal/objabi/reloctype.go +index 996c300d95..241a79817c 100644 +--- a/src/cmd/internal/objabi/reloctype.go ++++ b/src/cmd/internal/objabi/reloctype.go +@@ -316,6 +316,11 @@ const ( + R_LOONG64_TLS_IE_PCREL_HI + R_LOONG64_TLS_IE_LO + ++ // R_LOONG64_GOTPCREL_HI and R_LOONG64_GOT_LO relocates an pcalau12i, ld.d pair to compute ++ // the address of the GOT slot of the referenced symbol. ++ R_LOONG64_GOTPCREL_HI ++ R_LOONG64_GOT_LO ++ + // R_JMPLOONG64 resolves to non-PC-relative target address of a JMP instruction, + // by encoding the address into the instruction. + R_JMPLOONG64 +diff --git a/src/cmd/internal/objabi/reloctype_string.go b/src/cmd/internal/objabi/reloctype_string.go +index c7441efa28..e0649a5b0a 100644 +--- a/src/cmd/internal/objabi/reloctype_string.go ++++ b/src/cmd/internal/objabi/reloctype_string.go +@@ -81,19 +81,21 @@ func _() { + _ = x[R_CALLLOONG64-71] + _ = x[R_LOONG64_TLS_IE_PCREL_HI-72] + _ = x[R_LOONG64_TLS_IE_LO-73] +- _ = x[R_JMPLOONG64-74] +- _ = x[R_ADDRMIPSU-75] +- _ = x[R_ADDRMIPSTLS-76] +- _ = x[R_ADDRCUOFF-77] +- _ = x[R_WASMIMPORT-78] +- _ = x[R_XCOFFREF-79] +- _ = x[R_PEIMAGEOFF-80] +- _ = x[R_INITORDER-81] ++ _ = x[R_LOONG64_GOTPCREL_HI-74] ++ _ = x[R_LOONG64_GOT_LO-75] ++ _ = x[R_JMPLOONG64-76] ++ _ = x[R_ADDRMIPSU-77] ++ _ = x[R_ADDRMIPSTLS-78] ++ _ = x[R_ADDRCUOFF-79] ++ _ = x[R_WASMIMPORT-80] ++ _ = x[R_XCOFFREF-81] ++ _ = x[R_PEIMAGEOFF-82] ++ _ = x[R_INITORDER-83] + } + +-const _RelocType_name = "R_ADDRR_ADDRPOWERR_ADDRARM64R_ADDRMIPSR_ADDROFFR_SIZER_CALLR_CALLARMR_CALLARM64R_CALLINDR_CALLPOWERR_CALLMIPSR_CONSTR_PCRELR_TLS_LER_TLS_IER_GOTOFFR_PLT0R_PLT1R_PLT2R_USEFIELDR_USETYPER_USEIFACER_USEIFACEMETHODR_USEGENERICIFACEMETHODR_METHODOFFR_KEEPR_POWER_TOCR_GOTPCRELR_JMPMIPSR_DWARFSECREFR_DWARFFILEREFR_ARM64_TLS_LER_ARM64_TLS_IER_ARM64_GOTPCRELR_ARM64_GOTR_ARM64_PCRELR_ARM64_PCREL_LDST8R_ARM64_PCREL_LDST16R_ARM64_PCREL_LDST32R_ARM64_PCREL_LDST64R_ARM64_LDST8R_ARM64_LDST16R_ARM64_LDST32R_ARM64_LDST64R_ARM64_LDST128R_POWER_TLS_LER_POWER_TLS_IER_POWER_TLSR_POWER_TLS_IE_PCREL34R_POWER_TLS_LE_TPREL34R_ADDRPOWER_DSR_ADDRPOWER_GOTR_ADDRPOWER_GOT_PCREL34R_ADDRPOWER_PCRELR_ADDRPOWER_TOCRELR_ADDRPOWER_TOCREL_DSR_ADDRPOWER_D34R_ADDRPOWER_PCREL34R_RISCV_CALLR_RISCV_CALL_TRAMPR_RISCV_PCREL_ITYPER_RISCV_PCREL_STYPER_RISCV_TLS_IE_ITYPER_RISCV_TLS_IE_STYPER_PCRELDBLR_ADDRLOONG64R_ADDRLOONG64UR_ADDRLOONG64TLSR_ADDRLOONG64TLSUR_CALLLOONG64R_LOONG64_TLS_IE_PCREL_HIR_LOONG64_TLS_IE_LOR_JMPLOONG64R_ADDRMIPSUR_ADDRMIPSTLSR_ADDRCUOFFR_WASMIMPORTR_XCOFFREFR_PEIMAGEOFFR_INITORDER" ++const _RelocType_name = "R_ADDRR_ADDRPOWERR_ADDRARM64R_ADDRMIPSR_ADDROFFR_SIZER_CALLR_CALLARMR_CALLARM64R_CALLINDR_CALLPOWERR_CALLMIPSR_CONSTR_PCRELR_TLS_LER_TLS_IER_GOTOFFR_PLT0R_PLT1R_PLT2R_USEFIELDR_USETYPER_USEIFACER_USEIFACEMETHODR_USEGENERICIFACEMETHODR_METHODOFFR_KEEPR_POWER_TOCR_GOTPCRELR_JMPMIPSR_DWARFSECREFR_DWARFFILEREFR_ARM64_TLS_LER_ARM64_TLS_IER_ARM64_GOTPCRELR_ARM64_GOTR_ARM64_PCRELR_ARM64_PCREL_LDST8R_ARM64_PCREL_LDST16R_ARM64_PCREL_LDST32R_ARM64_PCREL_LDST64R_ARM64_LDST8R_ARM64_LDST16R_ARM64_LDST32R_ARM64_LDST64R_ARM64_LDST128R_POWER_TLS_LER_POWER_TLS_IER_POWER_TLSR_POWER_TLS_IE_PCREL34R_POWER_TLS_LE_TPREL34R_ADDRPOWER_DSR_ADDRPOWER_GOTR_ADDRPOWER_GOT_PCREL34R_ADDRPOWER_PCRELR_ADDRPOWER_TOCRELR_ADDRPOWER_TOCREL_DSR_ADDRPOWER_D34R_ADDRPOWER_PCREL34R_RISCV_CALLR_RISCV_CALL_TRAMPR_RISCV_PCREL_ITYPER_RISCV_PCREL_STYPER_RISCV_TLS_IE_ITYPER_RISCV_TLS_IE_STYPER_PCRELDBLR_ADDRLOONG64R_ADDRLOONG64UR_ADDRLOONG64TLSR_ADDRLOONG64TLSUR_CALLLOONG64R_LOONG64_TLS_IE_PCREL_HIR_LOONG64_TLS_IE_LOR_LOONG64_GOTPCREL_HIR_LOONG64_GOT_LOR_JMPLOONG64R_ADDRMIPSUR_ADDRMIPSTLSR_ADDRCUOFFR_WASMIMPORTR_XCOFFREFR_PEIMAGEOFFR_INITORDER" + +-var _RelocType_index = [...]uint16{0, 6, 17, 28, 38, 47, 53, 59, 68, 79, 88, 99, 109, 116, 123, 131, 139, 147, 153, 159, 165, 175, 184, 194, 210, 233, 244, 250, 261, 271, 280, 293, 307, 321, 335, 351, 362, 375, 394, 414, 434, 454, 467, 481, 495, 509, 524, 538, 552, 563, 585, 607, 621, 636, 659, 676, 694, 715, 730, 749, 761, 779, 798, 817, 837, 857, 867, 880, 894, 910, 927, 940, 965, 984, 996, 1007, 1020, 1031, 1043, 1053, 1065, 1076} ++var _RelocType_index = [...]uint16{0, 6, 17, 28, 38, 47, 53, 59, 68, 79, 88, 99, 109, 116, 123, 131, 139, 147, 153, 159, 165, 175, 184, 194, 210, 233, 244, 250, 261, 271, 280, 293, 307, 321, 335, 351, 362, 375, 394, 414, 434, 454, 467, 481, 495, 509, 524, 538, 552, 563, 585, 607, 621, 636, 659, 676, 694, 715, 730, 749, 761, 779, 798, 817, 837, 857, 867, 880, 894, 910, 927, 940, 965, 984, 1005, 1021, 1033, 1044, 1057, 1068, 1080, 1090, 1102, 1113} + + func (i RelocType) String() string { + i -= 1 +diff --git a/src/cmd/link/internal/loong64/asm.go b/src/cmd/link/internal/loong64/asm.go +index 8f06068d78..d1296c3309 100644 +--- a/src/cmd/link/internal/loong64/asm.go ++++ b/src/cmd/link/internal/loong64/asm.go +@@ -14,7 +14,47 @@ import ( + "log" + ) + +-func gentext(ctxt *ld.Link, ldr *loader.Loader) {} ++func gentext(ctxt *ld.Link, ldr *loader.Loader) { ++ initfunc, addmoduledata := ld.PrepareAddmoduledata(ctxt) ++ if initfunc == nil { ++ return ++ } ++ ++ o := func(op uint32) { ++ initfunc.AddUint32(ctxt.Arch, op) ++ } ++ ++ // Emit the following function: ++ // ++ // local.dso_init: ++ // la.pcrel $a0, local.moduledata ++ // b runtime.addmoduledata ++ ++ // 0000000000000000 : ++ // 0: 1a000004 pcalau12i $a0, 0 ++ // 0: R_LARCH_PCALA_HI20 local.moduledata ++ o(0x1a000004) ++ rel, _ := initfunc.AddRel(objabi.R_ADDRLOONG64U) ++ rel.SetOff(0) ++ rel.SetSiz(4) ++ rel.SetSym(ctxt.Moduledata) ++ ++ // 4: 02c00084 addi.d $a0, $a0, 0 ++ // 4: R_LARCH_PCALA_LO12 local.moduledata ++ o(0x02c00084) ++ rel2, _ := initfunc.AddRel(objabi.R_ADDRLOONG64) ++ rel2.SetOff(4) ++ rel2.SetSiz(4) ++ rel2.SetSym(ctxt.Moduledata) ++ ++ // 8: 50000000 b 0 ++ // 8: R_LARCH_B26 runtime.addmoduledata ++ o(0x50000000) ++ rel3, _ := initfunc.AddRel(objabi.R_CALLLOONG64) ++ rel3.SetOff(8) ++ rel3.SetSiz(4) ++ rel3.SetSym(addmoduledata) ++} + + func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym, r loader.Reloc, rIdx int) bool { + log.Fatalf("adddynrel not implemented") +@@ -78,6 +118,16 @@ func elfreloc1(ctxt *ld.Link, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym, + out.Write64(uint64(sectoff)) + out.Write64(uint64(elf.R_LARCH_PCALA_HI20) | uint64(elfsym)<<32) + out.Write64(uint64(r.Xadd)) ++ ++ case objabi.R_LOONG64_GOTPCREL_HI: ++ out.Write64(uint64(sectoff)) ++ out.Write64(uint64(elf.R_LARCH_GOT_PC_HI20) | uint64(elfsym)<<32) ++ out.Write64(uint64(0x0)) ++ ++ case objabi.R_LOONG64_GOT_LO: ++ out.Write64(uint64(sectoff)) ++ out.Write64(uint64(elf.R_LARCH_GOT_PC_LO12) | uint64(elfsym)<<32) ++ out.Write64(uint64(0x0)) + } + + return true +@@ -98,6 +148,8 @@ func archreloc(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loade + default: + return val, 0, false + case objabi.R_ADDRLOONG64, ++ objabi.R_LOONG64_GOTPCREL_HI, ++ objabi.R_LOONG64_GOT_LO, + objabi.R_ADDRLOONG64U: + // set up addend for eventual relocation via outer symbol. + rs, _ := ld.FoldSubSymbolOffset(ldr, rs) +@@ -156,7 +208,10 @@ func archrelocvariant(*ld.Target, *loader.Loader, loader.Reloc, sym.RelocVariant + func extreloc(target *ld.Target, ldr *loader.Loader, r loader.Reloc, s loader.Sym) (loader.ExtReloc, bool) { + switch r.Type() { + case objabi.R_ADDRLOONG64, +- objabi.R_ADDRLOONG64U: ++ objabi.R_ADDRLOONG64U, ++ objabi.R_LOONG64_GOTPCREL_HI, ++ objabi.R_LOONG64_GOT_LO: ++ + return ld.ExtrelocViaOuterSym(ldr, r, s), true + + case objabi.R_ADDRLOONG64TLS, +diff --git a/src/internal/platform/supported.go b/src/internal/platform/supported.go +index 230a952d2d..abab4b0541 100644 +--- a/src/internal/platform/supported.go ++++ b/src/internal/platform/supported.go +@@ -199,14 +199,14 @@ func BuildModeSupported(compiler, buildmode, goos, goarch string) bool { + + case "shared": + switch platform { +- case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x": ++ case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/loong64", "linux/ppc64le", "linux/s390x": + return true + } + return false + + case "plugin": + switch platform { +- case "linux/amd64", "linux/arm", "linux/arm64", "linux/386", "linux/s390x", "linux/ppc64le", ++ case "linux/amd64", "linux/arm", "linux/arm64", "linux/386", "linux/loong64", "linux/s390x", "linux/ppc64le", + "android/amd64", "android/386", + "darwin/amd64", "darwin/arm64", + "freebsd/amd64": +diff --git a/src/runtime/asm_loong64.s b/src/runtime/asm_loong64.s +index 6ffa1392c4..78a1a4d358 100644 +--- a/src/runtime/asm_loong64.s ++++ b/src/runtime/asm_loong64.s +@@ -642,6 +642,17 @@ TEXT runtime·goexit(SB),NOSPLIT|NOFRAME|TOPFRAME,$0-0 + // traceback from goexit1 must hit code range of goexit + NOOP + ++// This is called from .init_array and follows the platform, not Go, ABI. ++TEXT runtime·addmoduledata(SB),NOSPLIT,$0-0 ++ ADDV $-0x10, R3 ++ MOVV R30, 8(R3) // The access to global variables below implicitly uses R30, which is callee-save ++ MOVV runtime·lastmoduledatap(SB), R12 ++ MOVV R4, moduledata_next(R12) ++ MOVV R4, runtime·lastmoduledatap(SB) ++ MOVV 8(R3), R30 ++ ADDV $0x10, R3 ++ RET ++ + TEXT ·checkASM(SB),NOSPLIT,$0-1 + MOVW $1, R19 + MOVB R19, ret+0(FP) +-- +2.20.1 + diff --git a/loongarch64/0002-runtime-cmd-go-enable-memory-sanitizer-on-linux-loon.patch b/loongarch64/0002-runtime-cmd-go-enable-memory-sanitizer-on-linux-loon.patch new file mode 100644 index 0000000000000000000000000000000000000000..b7028f52d0e805c0a141fc1cc26bbbde3bb305cd --- /dev/null +++ b/loongarch64/0002-runtime-cmd-go-enable-memory-sanitizer-on-linux-loon.patch @@ -0,0 +1,268 @@ +From 82fe04e68eb6dafa457e7f32ed6564a3d85fb78f Mon Sep 17 00:00:00 2001 +From: Xiaolin Zhao +Date: Fri, 31 Mar 2023 15:36:59 +0800 +Subject: [PATCH 02/51] runtime, cmd/go: enable memory sanitizer on + linux/loong64 + +Change-Id: If537c5ffb1c9d4b3316b9b3794d411953bc5764b +--- + src/cmd/go/alldocs.go | 2 +- + src/cmd/go/internal/work/build.go | 2 +- + src/internal/platform/supported.go | 2 +- + src/runtime/cgo/gcc_mmap.c | 2 +- + src/runtime/cgo/mmap.go | 2 +- + src/runtime/cgo_mmap.go | 2 +- + src/runtime/mmap.go | 2 +- + src/runtime/msan/msan.go | 2 +- + src/runtime/msan_loong64.s | 72 ++++++++++++++++++++++++++++++ + src/runtime/sys_linux_loong64.s | 37 +++++++++++++-- + 10 files changed, 113 insertions(+), 12 deletions(-) + create mode 100644 src/runtime/msan_loong64.s + +diff --git a/src/cmd/go/alldocs.go b/src/cmd/go/alldocs.go +index bb28756133..d8377d1fd6 100644 +--- a/src/cmd/go/alldocs.go ++++ b/src/cmd/go/alldocs.go +@@ -119,7 +119,7 @@ + // linux/ppc64le and linux/arm64 (only for 48-bit VMA). + // -msan + // enable interoperation with memory sanitizer. +-// Supported only on linux/amd64, linux/arm64, freebsd/amd64 ++// Supported only on linux/amd64, linux/arm64, linux/loong64, freebsd/amd64 + // and only with Clang/LLVM as the host C compiler. + // PIE build mode will be used on all platforms except linux/amd64. + // -asan +diff --git a/src/cmd/go/internal/work/build.go b/src/cmd/go/internal/work/build.go +index e2e0e07299..05e300581c 100644 +--- a/src/cmd/go/internal/work/build.go ++++ b/src/cmd/go/internal/work/build.go +@@ -76,7 +76,7 @@ and test commands: + linux/ppc64le and linux/arm64 (only for 48-bit VMA). + -msan + enable interoperation with memory sanitizer. +- Supported only on linux/amd64, linux/arm64, freebsd/amd64 ++ Supported only on linux/amd64, linux/arm64, linux/loong64, freebsd/amd64 + and only with Clang/LLVM as the host C compiler. + PIE build mode will be used on all platforms except linux/amd64. + -asan +diff --git a/src/internal/platform/supported.go b/src/internal/platform/supported.go +index abab4b0541..b4f8bb5496 100644 +--- a/src/internal/platform/supported.go ++++ b/src/internal/platform/supported.go +@@ -38,7 +38,7 @@ func RaceDetectorSupported(goos, goarch string) bool { + func MSanSupported(goos, goarch string) bool { + switch goos { + case "linux": +- return goarch == "amd64" || goarch == "arm64" ++ return goarch == "amd64" || goarch == "arm64" || goarch == "loong64" + case "freebsd": + return goarch == "amd64" + default: +diff --git a/src/runtime/cgo/gcc_mmap.c b/src/runtime/cgo/gcc_mmap.c +index 1fbd5e82a4..eb710a039d 100644 +--- a/src/runtime/cgo/gcc_mmap.c ++++ b/src/runtime/cgo/gcc_mmap.c +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build (linux && (amd64 || arm64 || ppc64le)) || (freebsd && amd64) ++//go:build (linux && (amd64 || arm64 || loong64 || ppc64le)) || (freebsd && amd64) + + #include + #include +diff --git a/src/runtime/cgo/mmap.go b/src/runtime/cgo/mmap.go +index 2f7e83bcb7..144af2b2ca 100644 +--- a/src/runtime/cgo/mmap.go ++++ b/src/runtime/cgo/mmap.go +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build (linux && amd64) || (linux && arm64) || (freebsd && amd64) ++//go:build (linux && (amd64 || arm64 || loong64)) || (freebsd && amd64) + + package cgo + +diff --git a/src/runtime/cgo_mmap.go b/src/runtime/cgo_mmap.go +index 30660f7784..36d776e628 100644 +--- a/src/runtime/cgo_mmap.go ++++ b/src/runtime/cgo_mmap.go +@@ -4,7 +4,7 @@ + + // Support for memory sanitizer. See runtime/cgo/mmap.go. + +-//go:build (linux && amd64) || (linux && arm64) || (freebsd && amd64) ++//go:build (linux && (amd64 || arm64 || loong64)) || (freebsd && amd64) + + package runtime + +diff --git a/src/runtime/mmap.go b/src/runtime/mmap.go +index f0183f61cf..9a7b298562 100644 +--- a/src/runtime/mmap.go ++++ b/src/runtime/mmap.go +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build !aix && !darwin && !js && (!linux || !amd64) && (!linux || !arm64) && (!freebsd || !amd64) && !openbsd && !plan9 && !solaris && !windows ++//go:build !aix && !darwin && !js && !((linux && (amd64 || arm64 || loong64)) || (freebsd && amd64)) && !openbsd && !plan9 && !solaris && !windows + + package runtime + +diff --git a/src/runtime/msan/msan.go b/src/runtime/msan/msan.go +index 4e41f8528d..7b3e8e608d 100644 +--- a/src/runtime/msan/msan.go ++++ b/src/runtime/msan/msan.go +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build msan && ((linux && (amd64 || arm64)) || (freebsd && amd64)) ++//go:build msan && ((linux && (amd64 || arm64 || loong64)) || (freebsd && amd64)) + + package msan + +diff --git a/src/runtime/msan_loong64.s b/src/runtime/msan_loong64.s +new file mode 100644 +index 0000000000..dcd7940ed8 +--- /dev/null ++++ b/src/runtime/msan_loong64.s +@@ -0,0 +1,72 @@ ++// Copyright 2023 The Go Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style ++// license that can be found in the LICENSE file. ++ ++//go:build msan ++ ++#include "go_asm.h" ++#include "textflag.h" ++ ++#define RARG0 R4 ++#define RARG1 R5 ++#define RARG2 R6 ++#define FARG R7 ++ ++// func runtime·domsanread(addr unsafe.Pointer, sz uintptr) ++// Called from msanread. ++TEXT runtime·domsanread(SB), NOSPLIT, $0-16 ++ MOVV addr+0(FP), RARG0 ++ MOVV size+8(FP), RARG1 ++ // void __msan_read_go(void *addr, uintptr_t sz); ++ MOVV $__msan_read_go(SB), FARG ++ JMP msancall<>(SB) ++ ++// func runtime·msanwrite(addr unsafe.Pointer, sz uintptr) ++// Called from instrumented code. ++TEXT runtime·msanwrite(SB), NOSPLIT, $0-16 ++ MOVV addr+0(FP), RARG0 ++ MOVV size+8(FP), RARG1 ++ // void __msan_write_go(void *addr, uintptr_t sz); ++ MOVV $__msan_write_go(SB), FARG ++ JMP msancall<>(SB) ++ ++// func runtime·msanmalloc(addr unsafe.Pointer, sz uintptr) ++TEXT runtime·msanmalloc(SB), NOSPLIT, $0-16 ++ MOVV addr+0(FP), RARG0 ++ MOVV size+8(FP), RARG1 ++ // void __msan_malloc_go(void *addr, uintptr_t sz); ++ MOVV $__msan_malloc_go(SB), FARG ++ JMP msancall<>(SB) ++ ++// func runtime·msanfree(addr unsafe.Pointer, sz uintptr) ++TEXT runtime·msanfree(SB), NOSPLIT, $0-16 ++ MOVV addr+0(FP), RARG0 ++ MOVV size+8(FP), RARG1 ++ // void __msan_free_go(void *addr, uintptr_t sz); ++ MOVV $__msan_free_go(SB), FARG ++ JMP msancall<>(SB) ++ ++// func runtime·msanmove(dst, src unsafe.Pointer, sz uintptr) ++TEXT runtime·msanmove(SB), NOSPLIT, $0-24 ++ MOVV dst+0(FP), RARG0 ++ MOVV src+8(FP), RARG1 ++ MOVV size+16(FP), RARG2 ++ // void __msan_memmove(void *dst, void *src, uintptr_t sz); ++ MOVV $__msan_memmove(SB), FARG ++ JMP msancall<>(SB) ++ ++// Switches SP to g0 stack and calls (FARG). Arguments already set. ++TEXT msancall<>(SB), NOSPLIT, $0-0 ++ MOVV R3, R23 // callee-saved ++ BEQ g, g0stack // no g, still on a system stack ++ MOVV g_m(g), R14 ++ MOVV m_g0(R14), R15 ++ BEQ R15, g, g0stack ++ ++ MOVV (g_sched+gobuf_sp)(R15), R9 ++ MOVV R9, R3 ++ ++g0stack: ++ JAL (FARG) ++ MOVV R23, R3 ++ RET +diff --git a/src/runtime/sys_linux_loong64.s b/src/runtime/sys_linux_loong64.s +index 12e5455345..eba8e1f24c 100644 +--- a/src/runtime/sys_linux_loong64.s ++++ b/src/runtime/sys_linux_loong64.s +@@ -461,8 +461,8 @@ TEXT runtime·sigtramp(SB),NOSPLIT|TOPFRAME,$168 + TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0 + JMP runtime·sigtramp(SB) + +-// func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) (p unsafe.Pointer, err int) +-TEXT runtime·mmap(SB),NOSPLIT|NOFRAME,$0 ++// func sysMmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) (p unsafe.Pointer, err int) ++TEXT runtime·sysMmap(SB),NOSPLIT|NOFRAME,$0 + MOVV addr+0(FP), R4 + MOVV n+8(FP), R5 + MOVW prot+16(FP), R6 +@@ -483,8 +483,25 @@ ok: + MOVV $0, err+40(FP) + RET + +-// func munmap(addr unsafe.Pointer, n uintptr) +-TEXT runtime·munmap(SB),NOSPLIT|NOFRAME,$0 ++// Call the function stored in _cgo_mmap using the GCC calling convention. ++// This must be called on the system stack. ++// func callCgoMmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) uintptr ++TEXT runtime·callCgoMmap(SB),NOSPLIT,$0 ++ MOVV addr+0(FP), R4 ++ MOVV n+8(FP), R5 ++ MOVW prot+16(FP), R6 ++ MOVW flags+20(FP), R7 ++ MOVW fd+24(FP), R8 ++ MOVW off+28(FP), R9 ++ MOVV _cgo_mmap(SB), R13 ++ SUBV $16, R3 // reserve 16 bytes for sp-8 where fp may be saved. ++ JAL (R13) ++ ADDV $16, R3 ++ MOVV R4, ret+32(FP) ++ RET ++ ++// func sysMunmap(addr unsafe.Pointer, n uintptr) ++TEXT runtime·sysMunmap(SB),NOSPLIT|NOFRAME,$0 + MOVV addr+0(FP), R4 + MOVV n+8(FP), R5 + MOVV $SYS_munmap, R11 +@@ -494,6 +511,18 @@ TEXT runtime·munmap(SB),NOSPLIT|NOFRAME,$0 + MOVV R0, 0xf3(R0) // crash + RET + ++// Call the function stored in _cgo_munmap using the GCC calling convention. ++// This must be called on the system stack. ++// func callCgoMunmap(addr unsafe.Pointer, n uintptr) ++TEXT runtime·callCgoMunmap(SB),NOSPLIT,$0 ++ MOVV addr+0(FP), R4 ++ MOVV n+8(FP), R5 ++ MOVV _cgo_munmap(SB), R13 ++ SUBV $16, R3 // reserve 16 bytes for sp-8 where fp may be saved. ++ JAL (R13) ++ ADDV $16, R3 ++ RET ++ + // func madvise(addr unsafe.Pointer, n uintptr, flags int32) + TEXT runtime·madvise(SB),NOSPLIT|NOFRAME,$0 + MOVV addr+0(FP), R4 +-- +2.20.1 + diff --git a/loongarch64/0003-runtime-cmd-go-enable-address-sanitizer-on-linux-loo.patch b/loongarch64/0003-runtime-cmd-go-enable-address-sanitizer-on-linux-loo.patch new file mode 100644 index 0000000000000000000000000000000000000000..f2a70b3e264547ff1c86357084a9cec337509ba9 --- /dev/null +++ b/loongarch64/0003-runtime-cmd-go-enable-address-sanitizer-on-linux-loo.patch @@ -0,0 +1,160 @@ +From e2e4138bdb0589fec3c959a63479bc0e09c04cf9 Mon Sep 17 00:00:00 2001 +From: Xiaolin Zhao +Date: Fri, 31 Mar 2023 17:08:44 +0800 +Subject: [PATCH 03/51] runtime, cmd/go: enable address sanitizer on + linux/loong64 + +Change-Id: I48a65f2f10e3dc488acd9c02ea1a1f37de192be0 +--- + src/cmd/go/alldocs.go | 5 +- + src/cmd/go/internal/work/build.go | 5 +- + src/internal/platform/supported.go | 2 +- + src/runtime/asan/asan.go | 2 +- + src/runtime/asan_loong64.s | 75 ++++++++++++++++++++++++++++++ + 5 files changed, 83 insertions(+), 6 deletions(-) + create mode 100644 src/runtime/asan_loong64.s + +diff --git a/src/cmd/go/alldocs.go b/src/cmd/go/alldocs.go +index d8377d1fd6..7de5a066dd 100644 +--- a/src/cmd/go/alldocs.go ++++ b/src/cmd/go/alldocs.go +@@ -124,9 +124,10 @@ + // PIE build mode will be used on all platforms except linux/amd64. + // -asan + // enable interoperation with address sanitizer. +-// Supported only on linux/arm64, linux/amd64. +-// Supported only on linux/amd64 or linux/arm64 and only with GCC 7 and higher ++// Supported only on linux/arm64, linux/amd64, linux/loong64. ++// Supported on linux/amd64 or linux/arm64 and only with GCC 7 and higher + // or Clang/LLVM 9 and higher. ++// And supported on linux/loong64 only with Clang/LLVM 16 and higher. + // -cover + // enable code coverage instrumentation. + // -covermode set,count,atomic +diff --git a/src/cmd/go/internal/work/build.go b/src/cmd/go/internal/work/build.go +index 05e300581c..8cb53b95d9 100644 +--- a/src/cmd/go/internal/work/build.go ++++ b/src/cmd/go/internal/work/build.go +@@ -81,9 +81,10 @@ and test commands: + PIE build mode will be used on all platforms except linux/amd64. + -asan + enable interoperation with address sanitizer. +- Supported only on linux/arm64, linux/amd64. +- Supported only on linux/amd64 or linux/arm64 and only with GCC 7 and higher ++ Supported only on linux/arm64, linux/amd64, linux/loong64. ++ Supported on linux/amd64 or linux/arm64 and only with GCC 7 and higher + or Clang/LLVM 9 and higher. ++ And supported on linux/loong64 only with Clang/LLVM 16 and higher. + -cover + enable code coverage instrumentation. + -covermode set,count,atomic +diff --git a/src/internal/platform/supported.go b/src/internal/platform/supported.go +index b4f8bb5496..715bfb5e48 100644 +--- a/src/internal/platform/supported.go ++++ b/src/internal/platform/supported.go +@@ -51,7 +51,7 @@ func MSanSupported(goos, goarch string) bool { + func ASanSupported(goos, goarch string) bool { + switch goos { + case "linux": +- return goarch == "arm64" || goarch == "amd64" || goarch == "riscv64" || goarch == "ppc64le" ++ return goarch == "arm64" || goarch == "amd64" || goarch == "loong64" || goarch == "riscv64" || goarch == "ppc64le" + default: + return false + } +diff --git a/src/runtime/asan/asan.go b/src/runtime/asan/asan.go +index 25f15ae45b..ef70b0145b 100644 +--- a/src/runtime/asan/asan.go ++++ b/src/runtime/asan/asan.go +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build asan && linux && (arm64 || amd64 || riscv64 || ppc64le) ++//go:build asan && linux && (arm64 || amd64 || loong64 || riscv64 || ppc64le) + + package asan + +diff --git a/src/runtime/asan_loong64.s b/src/runtime/asan_loong64.s +new file mode 100644 +index 0000000000..8cef686217 +--- /dev/null ++++ b/src/runtime/asan_loong64.s +@@ -0,0 +1,75 @@ ++// Copyright 2023 The Go Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style ++// license that can be found in the LICENSE file. ++ ++//go:build asan ++ ++#include "go_asm.h" ++#include "textflag.h" ++ ++#define RARG0 R4 ++#define RARG1 R5 ++#define RARG2 R6 ++#define RARG3 R7 ++#define FARG R8 ++ ++// Called from instrumented code. ++// func runtime·doasanread(addr unsafe.Pointer, sz, sp, pc uintptr) ++TEXT runtime·doasanread(SB), NOSPLIT, $0-32 ++ MOVV addr+0(FP), RARG0 ++ MOVV size+8(FP), RARG1 ++ MOVV sp+16(FP), RARG2 ++ MOVV pc+24(FP), RARG3 ++ // void __asan_read_go(void *addr, uintptr_t sz, void *sp, void *pc); ++ MOVV $__asan_read_go(SB), FARG ++ JMP asancall<>(SB) ++ ++// func runtime·doasanwrite(addr unsafe.Pointer, sz, sp, pc uintptr) ++TEXT runtime·doasanwrite(SB), NOSPLIT, $0-32 ++ MOVV addr+0(FP), RARG0 ++ MOVV size+8(FP), RARG1 ++ MOVV sp+16(FP), RARG2 ++ MOVV pc+24(FP), RARG3 ++ // void __asan_write_go(void *addr, uintptr_t sz, void *sp, void *pc); ++ MOVV $__asan_write_go(SB), FARG ++ JMP asancall<>(SB) ++ ++// func runtime·asanunpoison(addr unsafe.Pointer, sz uintptr) ++TEXT runtime·asanunpoison(SB), NOSPLIT, $0-16 ++ MOVV addr+0(FP), RARG0 ++ MOVV size+8(FP), RARG1 ++ // void __asan_unpoison_go(void *addr, uintptr_t sz); ++ MOVV $__asan_unpoison_go(SB), FARG ++ JMP asancall<>(SB) ++ ++// func runtime·asanpoison(addr unsafe.Pointer, sz uintptr) ++TEXT runtime·asanpoison(SB), NOSPLIT, $0-16 ++ MOVV addr+0(FP), RARG0 ++ MOVV size+8(FP), RARG1 ++ // void __asan_poison_go(void *addr, uintptr_t sz); ++ MOVV $__asan_poison_go(SB), FARG ++ JMP asancall<>(SB) ++ ++// func runtime·asanregisterglobals(addr unsafe.Pointer, n uintptr) ++TEXT runtime·asanregisterglobals(SB), NOSPLIT, $0-16 ++ MOVV addr+0(FP), RARG0 ++ MOVV size+8(FP), RARG1 ++ // void __asan_register_globals_go(void *addr, uintptr_t n); ++ MOVV $__asan_register_globals_go(SB), FARG ++ JMP asancall<>(SB) ++ ++// Switches SP to g0 stack and calls (FARG). Arguments already set. ++TEXT asancall<>(SB), NOSPLIT, $0-0 ++ MOVV R3, R23 // callee-saved ++ BEQ g, g0stack // no g, still on a system stack ++ MOVV g_m(g), R14 ++ MOVV m_g0(R14), R15 ++ BEQ R15, g, g0stack ++ ++ MOVV (g_sched+gobuf_sp)(R15), R9 ++ MOVV R9, R3 ++ ++g0stack: ++ JAL (FARG) ++ MOVV R23, R3 ++ RET +-- +2.20.1 + diff --git a/loongarch64/0004-internal-sysinfo-print-cpu-type-from-cpuinfo-when-in.patch b/loongarch64/0004-internal-sysinfo-print-cpu-type-from-cpuinfo-when-in.patch new file mode 100644 index 0000000000000000000000000000000000000000..ff63f91cb67fd3a6507a43b77f4c1396ae32f9d6 --- /dev/null +++ b/loongarch64/0004-internal-sysinfo-print-cpu-type-from-cpuinfo-when-in.patch @@ -0,0 +1,194 @@ +From 947f77e67d82e05ec50770d38534f3c8b3fa0fda Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Tue, 11 Jul 2023 05:11:26 +0800 +Subject: [PATCH 04/51] internal/sysinfo: print cpu type from cpuinfo when + internal cpu name is empty on Linux + +Supports 386,amd64 and loong64 architectures on linux operating systems. + +Example output: +$ go test -bench=.* +goos: linux +goarch: loong64 +pkg: runtime +cpu: Loongson-3A5000-HV @ 2500.00MHz +BenchmarkSemTable/OneAddrCollision/n=1000 19261 62302 ns/op + ... + +Change-Id: I02db12d70c11327e4625bb6e59f30dfaf37c2db0 +--- + src/go/build/deps_test.go | 2 +- + src/internal/sysinfo/generic_os_cpuinfo.go | 11 +++++ + src/internal/sysinfo/proc_cpuinfo_linux.go | 41 +++++++++++++++++++ + .../sysinfo/proc_cpuinfo_linux_loong64.go | 33 +++++++++++++++ + .../sysinfo/proc_cpuinfo_linux_x84.go | 22 ++++++++++ + src/internal/sysinfo/sysinfo.go | 5 +++ + 6 files changed, 113 insertions(+), 1 deletion(-) + create mode 100644 src/internal/sysinfo/generic_os_cpuinfo.go + create mode 100644 src/internal/sysinfo/proc_cpuinfo_linux.go + create mode 100644 src/internal/sysinfo/proc_cpuinfo_linux_loong64.go + create mode 100644 src/internal/sysinfo/proc_cpuinfo_linux_x84.go + +diff --git a/src/go/build/deps_test.go b/src/go/build/deps_test.go +index 592f2fd72a..cd99bd2a63 100644 +--- a/src/go/build/deps_test.go ++++ b/src/go/build/deps_test.go +@@ -562,7 +562,7 @@ var depsRules = ` + < net/rpc/jsonrpc; + + # System Information +- internal/cpu, sync ++ internal/cpu, io, os, strings, sync + < internal/sysinfo; + + # Test-only +diff --git a/src/internal/sysinfo/generic_os_cpuinfo.go b/src/internal/sysinfo/generic_os_cpuinfo.go +new file mode 100644 +index 0000000000..ec3047bd3d +--- /dev/null ++++ b/src/internal/sysinfo/generic_os_cpuinfo.go +@@ -0,0 +1,11 @@ ++// Copyright 2023 The Go Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style ++// license that can be found in the LICENSE file. ++ ++//go:build !(linux && (386 || amd64 || loong64)) ++ ++package sysinfo ++ ++func osCpuInfoName() string { ++ return "" ++} +diff --git a/src/internal/sysinfo/proc_cpuinfo_linux.go b/src/internal/sysinfo/proc_cpuinfo_linux.go +new file mode 100644 +index 0000000000..cbe56fdae0 +--- /dev/null ++++ b/src/internal/sysinfo/proc_cpuinfo_linux.go +@@ -0,0 +1,41 @@ ++// Copyright 2023 The Go Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style ++// license that can be found in the LICENSE file. ++ ++package sysinfo ++ ++import ( ++ "io" ++ "os" ++ "strings" ++) ++ ++func readLinuxProcCPUInfo(buf []byte) error { ++ f, err := os.Open("/proc/cpuinfo") ++ if err != nil { ++ return err ++ } ++ defer f.Close() ++ ++ _, err = io.ReadFull(f, buf) ++ if err != nil && err != io.ErrUnexpectedEOF { ++ return err ++ } ++ ++ return nil ++} ++ ++func findCPUInfoField(buf []byte, fieldName string) string { ++ filedValue := string(buf[:len(buf)]) ++ n := strings.Index(filedValue, fieldName) ++ if n == -1 { ++ return "" ++ } ++ ++ filedValue = filedValue[n+len(fieldName):] ++ if n := strings.Index(filedValue, "\n"); n != -1 { ++ filedValue = filedValue[:n] ++ } ++ ++ return filedValue ++} +diff --git a/src/internal/sysinfo/proc_cpuinfo_linux_loong64.go b/src/internal/sysinfo/proc_cpuinfo_linux_loong64.go +new file mode 100644 +index 0000000000..3592998de6 +--- /dev/null ++++ b/src/internal/sysinfo/proc_cpuinfo_linux_loong64.go +@@ -0,0 +1,33 @@ ++// Copyright 2023 The Go Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style ++// license that can be found in the LICENSE file. ++ ++package sysinfo ++ ++const ( ++ // cpuinfo filed name ++ ModelName = "\nModel Name\t\t: " ++ CPUMHz = "\nCPU MHz\t\t\t: " ++) ++ ++func osCpuInfoName() string { ++ // The 512-byte buffer is enough to hold the contents of CPU0 ++ buf := make([]byte, 512) ++ err := readLinuxProcCPUInfo(buf) ++ if err != nil { ++ return "" ++ } ++ ++ modelName := findCPUInfoField(buf, ModelName) ++ cpuMHz := findCPUInfoField(buf, CPUMHz) ++ ++ if modelName == "" { ++ return "" ++ } ++ ++ if cpuMHz == "" { ++ return modelName ++ } ++ ++ return modelName + " @ " + cpuMHz + "MHz" ++} +diff --git a/src/internal/sysinfo/proc_cpuinfo_linux_x84.go b/src/internal/sysinfo/proc_cpuinfo_linux_x84.go +new file mode 100644 +index 0000000000..7b5d5b88f2 +--- /dev/null ++++ b/src/internal/sysinfo/proc_cpuinfo_linux_x84.go +@@ -0,0 +1,22 @@ ++// Copyright 2023 The Go Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style ++// license that can be found in the LICENSE file. ++ ++//go:build linux && (386 || amd64) ++ ++package sysinfo ++ ++const ( ++ // cpuinfo filed name ++ ModelName = "model name\t: " ++) ++ ++func osCpuInfoName() string { ++ buf := make([]byte, 512) ++ err := readLinuxProcCPUInfo(buf) ++ if err != nil { ++ return "" ++ } ++ ++ return findCPUInfoField(buf, ModelName) ++} +diff --git a/src/internal/sysinfo/sysinfo.go b/src/internal/sysinfo/sysinfo.go +index 961be7abae..19e841fb16 100644 +--- a/src/internal/sysinfo/sysinfo.go ++++ b/src/internal/sysinfo/sysinfo.go +@@ -26,6 +26,11 @@ func (cpu *cpuInfo) Name() string { + return + } + // TODO(martisch): use /proc/cpuinfo and /sys/devices/system/cpu/ on Linux as fallback. ++ if name := osCpuInfoName(); name != "" { ++ cpu.name = name ++ return ++ } + }) ++ + return cpu.name + } +-- +2.20.1 + diff --git a/loongarch64/0005-cmd-cmd-vendor-pick-up-updates-for-golang.org-x-arch.patch b/loongarch64/0005-cmd-cmd-vendor-pick-up-updates-for-golang.org-x-arch.patch new file mode 100644 index 0000000000000000000000000000000000000000..1c25af195eeb323971f59646a8fdd176a5ff7a33 --- /dev/null +++ b/loongarch64/0005-cmd-cmd-vendor-pick-up-updates-for-golang.org-x-arch.patch @@ -0,0 +1,2250 @@ +From 8f36ab9703a361398d0c9553a5fbac1ab6c0c846 Mon Sep 17 00:00:00 2001 +From: chenguoqi +Date: Fri, 10 Feb 2023 15:00:12 +0800 +Subject: [PATCH 05/51] cmd,cmd/vendor: pick up updates for + golang.org/x/arch/loong64 + +Bring in updates to golang.org/x/arch/ to support loong64 disassembler +from CL 358854. + + Used the directions found in README.vendor: + + cd $GOROOT/src/cmd + go get -d golang.org/x/arch@latest + go mod tidy + go mod vendor + +Change-Id: Ida0721ebd11caf4f116bb54a277606eaa38dc8ba +--- + .../x/arch/loong64/loong64asm/arg.go | 93 + + .../x/arch/loong64/loong64asm/decode.go | 269 +++ + .../x/arch/loong64/loong64asm/gnu.go | 16 + + .../x/arch/loong64/loong64asm/inst.go | 296 ++++ + .../x/arch/loong64/loong64asm/tables.go | 1513 +++++++++++++++++ + 5 files changed, 2187 insertions(+) + create mode 100644 src/cmd/vendor/golang.org/x/arch/loong64/loong64asm/arg.go + create mode 100644 src/cmd/vendor/golang.org/x/arch/loong64/loong64asm/decode.go + create mode 100644 src/cmd/vendor/golang.org/x/arch/loong64/loong64asm/gnu.go + create mode 100644 src/cmd/vendor/golang.org/x/arch/loong64/loong64asm/inst.go + create mode 100644 src/cmd/vendor/golang.org/x/arch/loong64/loong64asm/tables.go + +diff --git a/src/cmd/vendor/golang.org/x/arch/loong64/loong64asm/arg.go b/src/cmd/vendor/golang.org/x/arch/loong64/loong64asm/arg.go +new file mode 100644 +index 0000000000..9496e8c34d +--- /dev/null ++++ b/src/cmd/vendor/golang.org/x/arch/loong64/loong64asm/arg.go +@@ -0,0 +1,93 @@ ++// Copyright 2022 The Go Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style ++// license that can be found in the LICENSE file. ++ ++package loong64asm ++ ++// Naming for Go decoder arguments: ++// ++// - arg_fd: a Floating Point operand register fd encoded in the fd[4:0] field ++// ++// - arg_fj: a Floating Point operand register fj encoded in the fj[9:5] field ++// ++// - arg_fk: a Floating Point operand register fk encoded in the fk[14:10] field ++// ++// - arg_fa: a Floating Point operand register fa encoded in the fa[19:15] field ++// ++// - arg_rd: a general-purpose register rd encoded in the rd[4:0] field ++// ++// - arg_rj: a general-purpose register rj encoded in the rj[9:5] field ++// ++// - arg_rk: a general-purpose register rk encoded in the rk[14:10] field ++// ++// - arg_fcsr_4_0: float control status register encoded in [4:0] field ++// ++// - arg_cd_2_0: condition flag register encoded in [2:0] field ++// ++// - arg_sa2_16_15: shift bits constant encoded in [16:15] field ++// ++// - arg_code_14_0: arg for exception process routine encoded in [14:0] field ++// ++// - arg_ui5_14_10: 5bits unsigned immediate ++// ++// - arg_lsbw: For details, please refer to chapter 2.2.3.8 of instruction manual ++// ++// - arg_msbw: For details, please refer to chapter 2.2.3.9 of instruction manual ++// ++// - arg_hint_4_0: hint field implied the prefetch type and the data should fetch to cache's level ++// 0: load to data cache level 1 ++// 8: store to data cache level 1 ++// other: no define ++// ++// - arg_si12_21_10: 12bits signed immediate ++ ++type instArg uint16 ++ ++const ( ++ _ instArg = iota ++ //1-5 ++ arg_fd ++ arg_fj ++ arg_fk ++ arg_fa ++ arg_rd ++ //6-10 ++ arg_rj ++ arg_rk ++ arg_op_4_0 ++ arg_fcsr_4_0 ++ arg_fcsr_9_5 ++ //11-15 ++ arg_csr_23_10 ++ arg_cd ++ arg_cj ++ arg_ca ++ arg_sa2_16_15 ++ //16-20 ++ arg_sa3_17_15 ++ arg_code_4_0 ++ arg_code_14_0 ++ arg_ui5_14_10 ++ arg_ui6_15_10 ++ //21-25 ++ arg_ui12_21_10 ++ arg_lsbw ++ arg_msbw ++ arg_lsbd ++ arg_msbd ++ //26-30 ++ arg_hint_4_0 ++ arg_hint_14_0 ++ arg_level_14_0 ++ arg_level_17_10 ++ arg_seq_17_10 ++ //31-35 ++ arg_si12_21_10 ++ arg_si14_23_10 ++ arg_si16_25_10 ++ arg_si20_24_5 ++ arg_offset_20_0 ++ //36~ ++ arg_offset_25_0 ++ arg_offset_15_0 ++) +diff --git a/src/cmd/vendor/golang.org/x/arch/loong64/loong64asm/decode.go b/src/cmd/vendor/golang.org/x/arch/loong64/loong64asm/decode.go +new file mode 100644 +index 0000000000..ac3448f170 +--- /dev/null ++++ b/src/cmd/vendor/golang.org/x/arch/loong64/loong64asm/decode.go +@@ -0,0 +1,269 @@ ++// Copyright 2022 The Go Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style ++// license that can be found in the LICENSE file. ++ ++package loong64asm ++ ++import ( ++ "encoding/binary" ++ "fmt" ++) ++ ++type instArgs [5]instArg ++ ++// An instFormat describes the format of an instruction encoding. ++type instFormat struct { ++ mask uint32 ++ value uint32 ++ op Op ++ // args describe how to decode the instruction arguments. ++ // args is stored as a fixed-size array. ++ // if there are fewer than len(args) arguments, args[i] == 0 marks ++ // the end of the argument list. ++ args instArgs ++} ++ ++var ( ++ errShort = fmt.Errorf("truncated instruction") ++ errUnknown = fmt.Errorf("unknown instruction") ++) ++ ++var decoderCover []bool ++ ++func init() { ++ decoderCover = make([]bool, len(instFormats)) ++} ++ ++// Decode decodes the 4 bytes in src as a single instruction. ++func Decode(src []byte) (inst Inst, err error) { ++ if len(src) < 4 { ++ return Inst{}, errShort ++ } ++ ++ x := binary.LittleEndian.Uint32(src) ++ ++Search: ++ for i := range instFormats { ++ f := &instFormats[i] ++ ++ if (x & f.mask) != f.value { ++ continue ++ } ++ ++ // Decode args. ++ var args Args ++ for j, aop := range f.args { ++ if aop == 0 { ++ break ++ } ++ ++ arg := decodeArg(aop, x, i) ++ if arg == nil { ++ // Cannot decode argument ++ continue Search ++ } ++ ++ args[j] = arg ++ } ++ ++ decoderCover[i] = true ++ inst = Inst{ ++ Op: f.op, ++ Args: args, ++ Enc: x, ++ } ++ return inst, nil ++ } ++ ++ return Inst{}, errUnknown ++} ++ ++// decodeArg decodes the arg described by aop from the instruction bits x. ++// It returns nil if x cannot be decoded according to aop. ++func decodeArg(aop instArg, x uint32, index int) Arg { ++ switch aop { ++ case arg_fd: ++ return F0 + Reg(x&((1<<5)-1)) ++ ++ case arg_fj: ++ return F0 + Reg((x>>5)&((1<<5)-1)) ++ ++ case arg_fk: ++ return F0 + Reg((x>>10)&((1<<5)-1)) ++ ++ case arg_fa: ++ return F0 + Reg((x>>15)&((1<<5)-1)) ++ ++ case arg_rd: ++ return R0 + Reg(x&((1<<5)-1)) ++ ++ case arg_rj: ++ return R0 + Reg((x>>5)&((1<<5)-1)) ++ ++ case arg_rk: ++ return R0 + Reg((x>>10)&((1<<5)-1)) ++ ++ case arg_fcsr_4_0: ++ return FCSR0 + Fcsr(x&((1<<5)-1)) ++ ++ case arg_fcsr_9_5: ++ return FCSR0 + Fcsr((x>>5)&((1<<5)-1)) ++ ++ case arg_cd: ++ return FCC0 + Fcc(x&((1<<3)-1)) ++ ++ case arg_cj: ++ return FCC0 + Fcc((x>>5)&((1<<3)-1)) ++ ++ case arg_ca: ++ return FCC0 + Fcc((x>>15)&((1<<3)-1)) ++ ++ case arg_op_4_0: ++ tmp := x & ((1 << 5) - 1) ++ return Uimm{tmp, false} ++ ++ case arg_csr_23_10: ++ tmp := (x >> 10) & ((1 << 14) - 1) ++ return Uimm{tmp, false} ++ ++ case arg_sa2_16_15: ++ f := &instFormats[index] ++ tmp := SaSimm((x >> 15) & ((1 << 2) - 1)) ++ if (f.op == ALSL_D) || (f.op == ALSL_W) || (f.op == ALSL_WU) { ++ return tmp + 1 ++ } else { ++ return tmp + 0 ++ } ++ ++ case arg_sa3_17_15: ++ return SaSimm((x >> 15) & ((1 << 3) - 1)) ++ ++ case arg_code_4_0: ++ return CodeSimm(x & ((1 << 5) - 1)) ++ ++ case arg_code_14_0: ++ return CodeSimm(x & ((1 << 15) - 1)) ++ ++ case arg_ui5_14_10: ++ tmp := (x >> 10) & ((1 << 5) - 1) ++ return Uimm{tmp, false} ++ ++ case arg_ui6_15_10: ++ tmp := (x >> 10) & ((1 << 6) - 1) ++ return Uimm{tmp, false} ++ ++ case arg_ui12_21_10: ++ tmp := ((x >> 10) & ((1 << 12) - 1) & 0xfff) ++ return Uimm{tmp, false} ++ ++ case arg_lsbw: ++ tmp := (x >> 10) & ((1 << 5) - 1) ++ return Uimm{tmp, false} ++ ++ case arg_msbw: ++ tmp := (x >> 16) & ((1 << 5) - 1) ++ return Uimm{tmp, false} ++ ++ case arg_lsbd: ++ tmp := (x >> 10) & ((1 << 6) - 1) ++ return Uimm{tmp, false} ++ ++ case arg_msbd: ++ tmp := (x >> 16) & ((1 << 6) - 1) ++ return Uimm{tmp, false} ++ ++ case arg_hint_4_0: ++ tmp := int16(x & ((1 << 5) - 1)) ++ return Simm16{tmp, 4} ++ ++ case arg_hint_14_0: ++ tmp := int16(x & ((1 << 15) - 1)) ++ return Simm16{tmp, 15} ++ ++ case arg_level_14_0: ++ tmp := x & ((1 << 15) - 1) ++ return Uimm{tmp, false} ++ ++ case arg_level_17_10: ++ tmp := (x >> 10) & ((1 << 8) - 1) ++ return Uimm{tmp, false} ++ ++ case arg_seq_17_10: ++ tmp := (x >> 10) & ((1 << 8) - 1) ++ return Uimm{tmp, false} ++ ++ case arg_si12_21_10: ++ var tmp int16 ++ ++ //no int12, so sign-extend a 12-bit signed to 16-bit signed ++ if (x & 0x200000) == 0x200000 { ++ tmp = int16(((x >> 10) & ((1 << 12) - 1)) | 0xf000) ++ } else { ++ tmp = int16(((x >> 10) & ((1 << 12) - 1)) | 0x0000) ++ } ++ return Simm16{tmp, 12} ++ ++ case arg_si14_23_10: ++ var tmp int32 ++ if (x & 0x800000) == 0x800000 { ++ tmp = int32((((x >> 10) & ((1 << 14) - 1)) << 2) | 0xffff0000) ++ } else { ++ tmp = int32((((x >> 10) & ((1 << 14) - 1)) << 2) | 0x00000000) ++ } ++ return Simm32{tmp, 16} ++ ++ case arg_si16_25_10: ++ var tmp int32 ++ ++ if (x & 0x2000000) == 0x2000000 { ++ tmp = int32(((x >> 10) & ((1 << 16) - 1)) | 0xffff0000) ++ } else { ++ tmp = int32(((x >> 10) & ((1 << 16) - 1)) | 0x00000000) ++ } ++ ++ return Simm32{tmp, 16} ++ ++ case arg_si20_24_5: ++ var tmp int32 ++ if (x & 0x1000000) == 0x1000000 { ++ tmp = int32(((x >> 5) & ((1 << 20) - 1)) | 0xfff00000) ++ } else { ++ tmp = int32(((x >> 5) & ((1 << 20) - 1)) | 0x00000000) ++ } ++ return Simm32{tmp, 20} ++ ++ case arg_offset_20_0: ++ var tmp int32 ++ ++ if (x & 0x1000000) == 0x1000000 { ++ tmp = int32((((x << 16) | ((x >> 10) & ((1 << 16) - 1))) & ((1 << 21) - 1)) << 2) ++ } else { ++ tmp = int32((((x << 16) | ((x >> 10) & ((1 << 16) - 1))) & ((1 << 21) - 1)) << 2) ++ } ++ ++ return OffsetSimm{tmp, 28} ++ ++ case arg_offset_15_0: ++ var tmp int32 ++ if (x & 0x2000000) == 0x2000000 { ++ tmp = int32((((x >> 10) & ((1 << 16) - 1)) << 2) | 0xfffc0000) ++ } else { ++ tmp = int32((((x >> 10) & ((1 << 16) - 1)) << 2) | 0x00000000) ++ } ++ ++ return OffsetSimm{tmp, 18} ++ ++ case arg_offset_25_0: ++ var tmp int32 ++ ++ if (x & 0x200) == 0x200 { ++ tmp = int32(((((x << 16) | ((x >> 10) & ((1 << 16) - 1))) & ((1 << 26) - 1)) << 2) | 0xf0000000) ++ } else { ++ tmp = int32(((((x << 16) | ((x >> 10) & ((1 << 16) - 1))) & ((1 << 26) - 1)) << 2) | 0x00000000) ++ } ++ ++ return OffsetSimm{tmp, 28} ++ default: ++ return nil ++ } ++} +diff --git a/src/cmd/vendor/golang.org/x/arch/loong64/loong64asm/gnu.go b/src/cmd/vendor/golang.org/x/arch/loong64/loong64asm/gnu.go +new file mode 100644 +index 0000000000..fd6bcffde1 +--- /dev/null ++++ b/src/cmd/vendor/golang.org/x/arch/loong64/loong64asm/gnu.go +@@ -0,0 +1,16 @@ ++// Copyright 2022 The Go Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style ++// license that can be found in the LICENSE file. ++ ++package loong64asm ++ ++import ( ++ "strings" ++) ++ ++// GNUSyntax returns the GNU assembler syntax for the instruction, as defined by GNU binutils. ++// This form typically matches the syntax defined in the Loong64 Reference Manual. See ++// https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html ++func GNUSyntax(inst Inst) string { ++ return strings.ToLower(inst.String()) ++} +diff --git a/src/cmd/vendor/golang.org/x/arch/loong64/loong64asm/inst.go b/src/cmd/vendor/golang.org/x/arch/loong64/loong64asm/inst.go +new file mode 100644 +index 0000000000..187a46fc01 +--- /dev/null ++++ b/src/cmd/vendor/golang.org/x/arch/loong64/loong64asm/inst.go +@@ -0,0 +1,296 @@ ++// Copyright 2022 The Go Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style ++// license that can be found in the LICENSE file. ++ ++package loong64asm ++ ++import ( ++ "fmt" ++ "strconv" ++ "strings" ++ "unsafe" ++) ++ ++// An Inst is a single instruction. ++type Inst struct { ++ Op Op // Opcode mnemonic ++ Enc uint32 // Raw encoding bits. ++ Args Args // Instruction arguments, in Loong64 manual order. ++} ++ ++func (i Inst) String() string { ++ var args []string ++ ++ for _, arg := range i.Args { ++ if arg == nil { ++ break ++ } ++ ++ args = append(args, arg.String()) ++ } ++ ++ str2 := strings.Join(args, ", ") ++ if str2 == "" { ++ str := i.Op.String() ++ return strings.Replace(str, ", (", "(", -1) ++ } else { ++ str := i.Op.String() + " " + strings.Join(args, ", ") ++ return strings.Replace(str, ", (", "(", -1) ++ } ++} ++ ++// An Op is an Loong64 opcode. ++type Op uint16 ++ ++// NOTE: The actual Op values are defined in tables.go. ++// They are chosen to simplify instruction decoding and ++// are not a dense packing from 0 to N, although the ++// density is high, probably at least 90%. ++func (op Op) String() string { ++ if (op >= Op(len(opstr))) || (opstr[op] == "") { ++ return fmt.Sprintf("Op(%d)", int(op)) ++ } ++ ++ return opstr[op] ++} ++ ++// An Args holds the instruction arguments. ++// If an instruction has fewer than 5 arguments, ++// the final elements in the array are nil. ++type Args [5]Arg ++ ++// An Arg is a single instruction argument ++type Arg interface { ++ String() string ++} ++ ++// A Reg is a single register. ++// The zero value denotes R0, not the absence of a register. ++type Reg uint16 ++ ++const ( ++ //_ Reg = iota ++ ++ // General-purpose register ++ R0 Reg = iota ++ R1 ++ R2 ++ R3 ++ R4 ++ R5 ++ R6 ++ R7 ++ R8 ++ R9 ++ R10 ++ R11 ++ R12 ++ R13 ++ R14 ++ R15 ++ R16 ++ R17 ++ R18 ++ R19 ++ R20 ++ R21 ++ R22 ++ R23 ++ R24 ++ R25 ++ R26 ++ R27 ++ R28 ++ R29 ++ R30 ++ R31 ++ ++ // Float point register ++ F0 ++ F1 ++ F2 ++ F3 ++ F4 ++ F5 ++ F6 ++ F7 ++ F8 ++ F9 ++ F10 ++ F11 ++ F12 ++ F13 ++ F14 ++ F15 ++ F16 ++ F17 ++ F18 ++ F19 ++ F20 ++ F21 ++ F22 ++ F23 ++ F24 ++ F25 ++ F26 ++ F27 ++ F28 ++ F29 ++ F30 ++ F31 ++) ++ ++func (r Reg) String() string { ++ switch { ++ case r == R0: ++ return "$zero" ++ ++ case r == R1: ++ return "$ra" ++ ++ case r == R2: ++ return "$tp" ++ ++ case r == R3: ++ return "$sp" ++ ++ case (r >= R4) && (r <= R11): ++ return fmt.Sprintf("$a%d", int(r-R4)) ++ ++ case (r >= R12) && (r <= R20): ++ return fmt.Sprintf("$t%d", int(r-R12)) ++ ++ case r == R21: ++ return "$r21" ++ ++ case r == R22: ++ return "$fp" ++ ++ case (r >= R23) && (r <= R31): ++ return fmt.Sprintf("$s%d", int(r-R23)) ++ ++ case (r >= F0) && (r <= F7): ++ return fmt.Sprintf("$fa%d", int(r-F0)) ++ ++ case (r >= F8) && (r <= F23): ++ return fmt.Sprintf("$ft%d", int(r-F8)) ++ ++ case (r >= F24) && (r <= F31): ++ return fmt.Sprintf("$fs%d", int(r-F24)) ++ ++ default: ++ return fmt.Sprintf("Unknown(%d)", int(r)) ++ } ++} ++ ++// float control status register ++type Fcsr uint8 ++ ++const ( ++ //_ Fcsr = iota ++ FCSR0 Fcsr = iota ++ FCSR1 ++ FCSR2 ++ FCSR3 ++) ++ ++func (f Fcsr) String() string { ++ switch f { ++ case FCSR0: ++ return fmt.Sprintf("$zero") ++ case FCSR1, FCSR2, FCSR3: ++ return fmt.Sprintf("$r%d", uint8(f)) ++ } ++ ++ return fmt.Sprintf("$unknow%d", uint8(f)) ++} ++ ++// float condition flags register ++type Fcc uint8 ++ ++const ( ++ //_ Fcc = iota ++ FCC0 Fcc = iota ++ FCC1 ++ FCC2 ++ FCC3 ++ FCC4 ++ FCC5 ++ FCC6 ++ FCC7 ++) ++ ++func (f Fcc) String() string { ++ return fmt.Sprintf("$fcc%d", uint8(f)) ++} ++ ++// An Imm is an integer constant. ++type Uimm struct { ++ Imm uint32 ++ Decimal bool ++} ++ ++func (i Uimm) String() string { ++ if i.Decimal == true { ++ return fmt.Sprintf("%d", i.Imm) ++ } else { ++ return fmt.Sprintf("%#x", i.Imm) ++ } ++} ++ ++type Simm16 struct { ++ Imm int16 ++ Width uint8 ++} ++ ++func (si Simm16) String() string { ++ if si.Imm == 0 { ++ return fmt.Sprintf("%#x", int(si.Imm)) ++ } else { ++ hex := int16(si.Imm & ((1 << si.Width) - 1)) ++ str := strconv.FormatUint(uint64(*(*int16)(unsafe.Pointer(&hex))), 16) ++ return fmt.Sprintf("%d(0x%s)", int16(si.Imm), str) ++ } ++} ++ ++type Simm32 struct { ++ Imm int32 ++ Width uint8 ++} ++ ++func (si Simm32) String() string { ++ if si.Imm == 0 { ++ return fmt.Sprintf("%#x", int(si.Imm)) ++ } else { ++ hex := int32(si.Imm & ((1 << si.Width) - 1)) ++ str := strconv.FormatUint(uint64(*(*int32)(unsafe.Pointer(&hex))), 16) ++ return fmt.Sprintf("%d(0x%s)", int32(si.Imm), str) ++ } ++} ++ ++type OffsetSimm struct { ++ Imm int32 ++ Width uint8 ++} ++ ++func (o OffsetSimm) String() string { ++ if o.Imm == 0 { ++ return fmt.Sprintf("%#x", int(o.Imm)) ++ } else { ++ hex := int32(o.Imm & ((1 << o.Width) - 1)) ++ str := strconv.FormatUint(uint64(*(*int32)(unsafe.Pointer(&hex))), 16) ++ return fmt.Sprintf("%d(0x%s)", int32(o.Imm), str) ++ } ++} ++ ++type SaSimm int16 ++ ++func (s SaSimm) String() string { ++ return fmt.Sprintf("%#x", int(s)) ++} ++ ++type CodeSimm int16 ++ ++func (c CodeSimm) String() string { ++ return fmt.Sprintf("%#x", int(c)) ++} +diff --git a/src/cmd/vendor/golang.org/x/arch/loong64/loong64asm/tables.go b/src/cmd/vendor/golang.org/x/arch/loong64/loong64asm/tables.go +new file mode 100644 +index 0000000000..f90e9295f1 +--- /dev/null ++++ b/src/cmd/vendor/golang.org/x/arch/loong64/loong64asm/tables.go +@@ -0,0 +1,1513 @@ ++// Generated by Loong64 internal tool ++// DO NOT EDIT ++// Copyright 2022 The Go Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style ++// license that can be found in the LICENSE file. ++ ++package loong64asm ++ ++const ( ++ _ Op = iota ++ ADDI_D ++ ADDI_W ++ ADDU16I_D ++ ADD_D ++ ADD_W ++ ALSL_D ++ ALSL_W ++ ALSL_WU ++ AMADD_D ++ AMADD_DB_D ++ AMADD_DB_W ++ AMADD_W ++ AMAND_D ++ AMAND_DB_D ++ AMAND_DB_W ++ AMAND_W ++ AMMAX_D ++ AMMAX_DB_D ++ AMMAX_DB_DU ++ AMMAX_DB_W ++ AMMAX_DB_WU ++ AMMAX_DU ++ AMMAX_W ++ AMMAX_WU ++ AMMIN_D ++ AMMIN_DB_D ++ AMMIN_DB_DU ++ AMMIN_DB_W ++ AMMIN_DB_WU ++ AMMIN_DU ++ AMMIN_W ++ AMMIN_WU ++ AMOR_D ++ AMOR_DB_D ++ AMOR_DB_W ++ AMOR_W ++ AMSWAP_D ++ AMSWAP_DB_D ++ AMSWAP_DB_W ++ AMSWAP_W ++ AMXOR_D ++ AMXOR_DB_D ++ AMXOR_DB_W ++ AMXOR_W ++ AND ++ ANDI ++ ANDN ++ ASRTGT_D ++ ASRTLE_D ++ B ++ BCEQZ ++ BCNEZ ++ BEQ ++ BEQZ ++ BGE ++ BGEU ++ BITREV_4B ++ BITREV_8B ++ BITREV_D ++ BITREV_W ++ BL ++ BLT ++ BLTU ++ BNE ++ BNEZ ++ BREAK ++ BSTRINS_D ++ BSTRINS_W ++ BSTRPICK_D ++ BSTRPICK_W ++ BYTEPICK_D ++ BYTEPICK_W ++ CACOP ++ CLO_D ++ CLO_W ++ CLZ_D ++ CLZ_W ++ CPUCFG ++ CRCC_W_B_W ++ CRCC_W_D_W ++ CRCC_W_H_W ++ CRCC_W_W_W ++ CRC_W_B_W ++ CRC_W_D_W ++ CRC_W_H_W ++ CRC_W_W_W ++ CSRRD ++ CSRWR ++ CSRXCHG ++ CTO_D ++ CTO_W ++ CTZ_D ++ CTZ_W ++ DBAR ++ DBCL ++ DIV_D ++ DIV_DU ++ DIV_W ++ DIV_WU ++ ERTN ++ EXT_W_B ++ EXT_W_H ++ FABS_D ++ FABS_S ++ FADD_D ++ FADD_S ++ FCLASS_D ++ FCLASS_S ++ FCMP_CAF_D ++ FCMP_CAF_S ++ FCMP_CEQ_D ++ FCMP_CEQ_S ++ FCMP_CLE_D ++ FCMP_CLE_S ++ FCMP_CLT_D ++ FCMP_CLT_S ++ FCMP_CNE_D ++ FCMP_CNE_S ++ FCMP_COR_D ++ FCMP_COR_S ++ FCMP_CUEQ_D ++ FCMP_CUEQ_S ++ FCMP_CULE_D ++ FCMP_CULE_S ++ FCMP_CULT_D ++ FCMP_CULT_S ++ FCMP_CUNE_D ++ FCMP_CUNE_S ++ FCMP_CUN_D ++ FCMP_CUN_S ++ FCMP_SAF_D ++ FCMP_SAF_S ++ FCMP_SEQ_D ++ FCMP_SEQ_S ++ FCMP_SLE_D ++ FCMP_SLE_S ++ FCMP_SLT_D ++ FCMP_SLT_S ++ FCMP_SNE_D ++ FCMP_SNE_S ++ FCMP_SOR_D ++ FCMP_SOR_S ++ FCMP_SUEQ_D ++ FCMP_SUEQ_S ++ FCMP_SULE_D ++ FCMP_SULE_S ++ FCMP_SULT_D ++ FCMP_SULT_S ++ FCMP_SUNE_D ++ FCMP_SUNE_S ++ FCMP_SUN_D ++ FCMP_SUN_S ++ FCOPYSIGN_D ++ FCOPYSIGN_S ++ FCVT_D_S ++ FCVT_S_D ++ FDIV_D ++ FDIV_S ++ FFINT_D_L ++ FFINT_D_W ++ FFINT_S_L ++ FFINT_S_W ++ FLDGT_D ++ FLDGT_S ++ FLDLE_D ++ FLDLE_S ++ FLDX_D ++ FLDX_S ++ FLD_D ++ FLD_S ++ FLOGB_D ++ FLOGB_S ++ FMADD_D ++ FMADD_S ++ FMAXA_D ++ FMAXA_S ++ FMAX_D ++ FMAX_S ++ FMINA_D ++ FMINA_S ++ FMIN_D ++ FMIN_S ++ FMOV_D ++ FMOV_S ++ FMSUB_D ++ FMSUB_S ++ FMUL_D ++ FMUL_S ++ FNEG_D ++ FNEG_S ++ FNMADD_D ++ FNMADD_S ++ FNMSUB_D ++ FNMSUB_S ++ FRECIP_D ++ FRECIP_S ++ FRINT_D ++ FRINT_S ++ FRSQRT_D ++ FRSQRT_S ++ FSCALEB_D ++ FSCALEB_S ++ FSEL ++ FSQRT_D ++ FSQRT_S ++ FSTGT_D ++ FSTGT_S ++ FSTLE_D ++ FSTLE_S ++ FSTX_D ++ FSTX_S ++ FST_D ++ FST_S ++ FSUB_D ++ FSUB_S ++ FTINTRM_L_D ++ FTINTRM_L_S ++ FTINTRM_W_D ++ FTINTRM_W_S ++ FTINTRNE_L_D ++ FTINTRNE_L_S ++ FTINTRNE_W_D ++ FTINTRNE_W_S ++ FTINTRP_L_D ++ FTINTRP_L_S ++ FTINTRP_W_D ++ FTINTRP_W_S ++ FTINTRZ_L_D ++ FTINTRZ_L_S ++ FTINTRZ_W_D ++ FTINTRZ_W_S ++ FTINT_L_D ++ FTINT_L_S ++ FTINT_W_D ++ FTINT_W_S ++ IBAR ++ IDLE ++ INVTLB ++ IOCSRRD_B ++ IOCSRRD_D ++ IOCSRRD_H ++ IOCSRRD_W ++ IOCSRWR_B ++ IOCSRWR_D ++ IOCSRWR_H ++ IOCSRWR_W ++ JIRL ++ LDDIR ++ LDGT_B ++ LDGT_D ++ LDGT_H ++ LDGT_W ++ LDLE_B ++ LDLE_D ++ LDLE_H ++ LDLE_W ++ LDPTE ++ LDPTR_D ++ LDPTR_W ++ LDX_B ++ LDX_BU ++ LDX_D ++ LDX_H ++ LDX_HU ++ LDX_W ++ LDX_WU ++ LD_B ++ LD_BU ++ LD_D ++ LD_H ++ LD_HU ++ LD_W ++ LD_WU ++ LL_D ++ LL_W ++ LU12I_W ++ LU32I_D ++ LU52I_D ++ MASKEQZ ++ MASKNEZ ++ MOD_D ++ MOD_DU ++ MOD_W ++ MOD_WU ++ MOVCF2FR ++ MOVCF2GR ++ MOVFCSR2GR ++ MOVFR2CF ++ MOVFR2GR_D ++ MOVFR2GR_S ++ MOVFRH2GR_S ++ MOVGR2CF ++ MOVGR2FCSR ++ MOVGR2FRH_W ++ MOVGR2FR_D ++ MOVGR2FR_W ++ MULH_D ++ MULH_DU ++ MULH_W ++ MULH_WU ++ MULW_D_W ++ MULW_D_WU ++ MUL_D ++ MUL_W ++ NOR ++ OR ++ ORI ++ ORN ++ PCADDI ++ PCADDU12I ++ PCADDU18I ++ PCALAU12I ++ PRELD ++ PRELDX ++ RDTIMEH_W ++ RDTIMEL_W ++ RDTIME_D ++ REVB_2H ++ REVB_2W ++ REVB_4H ++ REVB_D ++ REVH_2W ++ REVH_D ++ ROTRI_D ++ ROTRI_W ++ ROTR_D ++ ROTR_W ++ SC_D ++ SC_W ++ SLLI_D ++ SLLI_W ++ SLL_D ++ SLL_W ++ SLT ++ SLTI ++ SLTU ++ SLTUI ++ SRAI_D ++ SRAI_W ++ SRA_D ++ SRA_W ++ SRLI_D ++ SRLI_W ++ SRL_D ++ SRL_W ++ STGT_B ++ STGT_D ++ STGT_H ++ STGT_W ++ STLE_B ++ STLE_D ++ STLE_H ++ STLE_W ++ STPTR_D ++ STPTR_W ++ STX_B ++ STX_D ++ STX_H ++ STX_W ++ ST_B ++ ST_D ++ ST_H ++ ST_W ++ SUB_D ++ SUB_W ++ SYSCALL ++ TLBCLR ++ TLBFILL ++ TLBFLUSH ++ TLBRD ++ TLBSRCH ++ TLBWR ++ XOR ++ XORI ++) ++ ++var opstr = [...]string{ ++ ADDI_D: "ADDI.D", ++ ADDI_W: "ADDI.W", ++ ADDU16I_D: "ADDU16I.D", ++ ADD_D: "ADD.D", ++ ADD_W: "ADD.W", ++ ALSL_D: "ALSL.D", ++ ALSL_W: "ALSL.W", ++ ALSL_WU: "ALSL.WU", ++ AMADD_D: "AMADD.D", ++ AMADD_DB_D: "AMADD_DB.D", ++ AMADD_DB_W: "AMADD_DB.W", ++ AMADD_W: "AMADD.W", ++ AMAND_D: "AMAND.D", ++ AMAND_DB_D: "AMAND_DB.D", ++ AMAND_DB_W: "AMAND_DB.W", ++ AMAND_W: "AMAND.W", ++ AMMAX_D: "AMMAX.D", ++ AMMAX_DB_D: "AMMAX_DB.D", ++ AMMAX_DB_DU: "AMMAX_DB.DU", ++ AMMAX_DB_W: "AMMAX_DB.W", ++ AMMAX_DB_WU: "AMMAX_DB.WU", ++ AMMAX_DU: "AMMAX.DU", ++ AMMAX_W: "AMMAX.W", ++ AMMAX_WU: "AMMAX.WU", ++ AMMIN_D: "AMMIN.D", ++ AMMIN_DB_D: "AMMIN_DB.D", ++ AMMIN_DB_DU: "AMMIN_DB.DU", ++ AMMIN_DB_W: "AMMIN_DB.W", ++ AMMIN_DB_WU: "AMMIN_DB.WU", ++ AMMIN_DU: "AMMIN.DU", ++ AMMIN_W: "AMMIN.W", ++ AMMIN_WU: "AMMIN.WU", ++ AMOR_D: "AMOR.D", ++ AMOR_DB_D: "AMOR_DB.D", ++ AMOR_DB_W: "AMOR_DB.W", ++ AMOR_W: "AMOR.W", ++ AMSWAP_D: "AMSWAP.D", ++ AMSWAP_DB_D: "AMSWAP_DB.D", ++ AMSWAP_DB_W: "AMSWAP_DB.W", ++ AMSWAP_W: "AMSWAP.W", ++ AMXOR_D: "AMXOR.D", ++ AMXOR_DB_D: "AMXOR_DB.D", ++ AMXOR_DB_W: "AMXOR_DB.W", ++ AMXOR_W: "AMXOR.W", ++ AND: "AND", ++ ANDI: "ANDI", ++ ANDN: "ANDN", ++ ASRTGT_D: "ASRTGT.D", ++ ASRTLE_D: "ASRTLE.D", ++ B: "B", ++ BCEQZ: "BCEQZ", ++ BCNEZ: "BCNEZ", ++ BEQ: "BEQ", ++ BEQZ: "BEQZ", ++ BGE: "BGE", ++ BGEU: "BGEU", ++ BITREV_4B: "BITREV.4B", ++ BITREV_8B: "BITREV.8B", ++ BITREV_D: "BITREV.D", ++ BITREV_W: "BITREV.W", ++ BL: "BL", ++ BLT: "BLT", ++ BLTU: "BLTU", ++ BNE: "BNE", ++ BNEZ: "BNEZ", ++ BREAK: "BREAK", ++ BSTRINS_D: "BSTRINS.D", ++ BSTRINS_W: "BSTRINS.W", ++ BSTRPICK_D: "BSTRPICK.D", ++ BSTRPICK_W: "BSTRPICK.W", ++ BYTEPICK_D: "BYTEPICK.D", ++ BYTEPICK_W: "BYTEPICK.W", ++ CACOP: "CACOP", ++ CLO_D: "CLO.D", ++ CLO_W: "CLO.W", ++ CLZ_D: "CLZ.D", ++ CLZ_W: "CLZ.W", ++ CPUCFG: "CPUCFG", ++ CRCC_W_B_W: "CRCC.W.B.W", ++ CRCC_W_D_W: "CRCC.W.D.W", ++ CRCC_W_H_W: "CRCC.W.H.W", ++ CRCC_W_W_W: "CRCC.W.W.W", ++ CRC_W_B_W: "CRC.W.B.W", ++ CRC_W_D_W: "CRC.W.D.W", ++ CRC_W_H_W: "CRC.W.H.W", ++ CRC_W_W_W: "CRC.W.W.W", ++ CSRRD: "CSRRD", ++ CSRWR: "CSRWR", ++ CSRXCHG: "CSRXCHG", ++ CTO_D: "CTO.D", ++ CTO_W: "CTO.W", ++ CTZ_D: "CTZ.D", ++ CTZ_W: "CTZ.W", ++ DBAR: "DBAR", ++ DBCL: "DBCL", ++ DIV_D: "DIV.D", ++ DIV_DU: "DIV.DU", ++ DIV_W: "DIV.W", ++ DIV_WU: "DIV.WU", ++ ERTN: "ERTN", ++ EXT_W_B: "EXT.W.B", ++ EXT_W_H: "EXT.W.H", ++ FABS_D: "FABS.D", ++ FABS_S: "FABS.S", ++ FADD_D: "FADD.D", ++ FADD_S: "FADD.S", ++ FCLASS_D: "FCLASS.D", ++ FCLASS_S: "FCLASS.S", ++ FCMP_CAF_D: "FCMP.CAF.D", ++ FCMP_CAF_S: "FCMP.CAF.S", ++ FCMP_CEQ_D: "FCMP.CEQ.D", ++ FCMP_CEQ_S: "FCMP.CEQ.S", ++ FCMP_CLE_D: "FCMP.CLE.D", ++ FCMP_CLE_S: "FCMP.CLE.S", ++ FCMP_CLT_D: "FCMP.CLT.D", ++ FCMP_CLT_S: "FCMP.CLT.S", ++ FCMP_CNE_D: "FCMP.CNE.D", ++ FCMP_CNE_S: "FCMP.CNE.S", ++ FCMP_COR_D: "FCMP.COR.D", ++ FCMP_COR_S: "FCMP.COR.S", ++ FCMP_CUEQ_D: "FCMP.CUEQ.D", ++ FCMP_CUEQ_S: "FCMP.CUEQ.S", ++ FCMP_CULE_D: "FCMP.CULE.D", ++ FCMP_CULE_S: "FCMP.CULE.S", ++ FCMP_CULT_D: "FCMP.CULT.D", ++ FCMP_CULT_S: "FCMP.CULT.S", ++ FCMP_CUNE_D: "FCMP.CUNE.D", ++ FCMP_CUNE_S: "FCMP.CUNE.S", ++ FCMP_CUN_D: "FCMP.CUN.D", ++ FCMP_CUN_S: "FCMP.CUN.S", ++ FCMP_SAF_D: "FCMP.SAF.D", ++ FCMP_SAF_S: "FCMP.SAF.S", ++ FCMP_SEQ_D: "FCMP.SEQ.D", ++ FCMP_SEQ_S: "FCMP.SEQ.S", ++ FCMP_SLE_D: "FCMP.SLE.D", ++ FCMP_SLE_S: "FCMP.SLE.S", ++ FCMP_SLT_D: "FCMP.SLT.D", ++ FCMP_SLT_S: "FCMP.SLT.S", ++ FCMP_SNE_D: "FCMP.SNE.D", ++ FCMP_SNE_S: "FCMP.SNE.S", ++ FCMP_SOR_D: "FCMP.SOR.D", ++ FCMP_SOR_S: "FCMP.SOR.S", ++ FCMP_SUEQ_D: "FCMP.SUEQ.D", ++ FCMP_SUEQ_S: "FCMP.SUEQ.S", ++ FCMP_SULE_D: "FCMP.SULE.D", ++ FCMP_SULE_S: "FCMP.SULE.S", ++ FCMP_SULT_D: "FCMP.SULT.D", ++ FCMP_SULT_S: "FCMP.SULT.S", ++ FCMP_SUNE_D: "FCMP.SUNE.D", ++ FCMP_SUNE_S: "FCMP.SUNE.S", ++ FCMP_SUN_D: "FCMP.SUN.D", ++ FCMP_SUN_S: "FCMP.SUN.S", ++ FCOPYSIGN_D: "FCOPYSIGN.D", ++ FCOPYSIGN_S: "FCOPYSIGN.S", ++ FCVT_D_S: "FCVT.D.S", ++ FCVT_S_D: "FCVT.S.D", ++ FDIV_D: "FDIV.D", ++ FDIV_S: "FDIV.S", ++ FFINT_D_L: "FFINT.D.L", ++ FFINT_D_W: "FFINT.D.W", ++ FFINT_S_L: "FFINT.S.L", ++ FFINT_S_W: "FFINT.S.W", ++ FLDGT_D: "FLDGT.D", ++ FLDGT_S: "FLDGT.S", ++ FLDLE_D: "FLDLE.D", ++ FLDLE_S: "FLDLE.S", ++ FLDX_D: "FLDX.D", ++ FLDX_S: "FLDX.S", ++ FLD_D: "FLD.D", ++ FLD_S: "FLD.S", ++ FLOGB_D: "FLOGB.D", ++ FLOGB_S: "FLOGB.S", ++ FMADD_D: "FMADD.D", ++ FMADD_S: "FMADD.S", ++ FMAXA_D: "FMAXA.D", ++ FMAXA_S: "FMAXA.S", ++ FMAX_D: "FMAX.D", ++ FMAX_S: "FMAX.S", ++ FMINA_D: "FMINA.D", ++ FMINA_S: "FMINA.S", ++ FMIN_D: "FMIN.D", ++ FMIN_S: "FMIN.S", ++ FMOV_D: "FMOV.D", ++ FMOV_S: "FMOV.S", ++ FMSUB_D: "FMSUB.D", ++ FMSUB_S: "FMSUB.S", ++ FMUL_D: "FMUL.D", ++ FMUL_S: "FMUL.S", ++ FNEG_D: "FNEG.D", ++ FNEG_S: "FNEG.S", ++ FNMADD_D: "FNMADD.D", ++ FNMADD_S: "FNMADD.S", ++ FNMSUB_D: "FNMSUB.D", ++ FNMSUB_S: "FNMSUB.S", ++ FRECIP_D: "FRECIP.D", ++ FRECIP_S: "FRECIP.S", ++ FRINT_D: "FRINT.D", ++ FRINT_S: "FRINT.S", ++ FRSQRT_D: "FRSQRT.D", ++ FRSQRT_S: "FRSQRT.S", ++ FSCALEB_D: "FSCALEB.D", ++ FSCALEB_S: "FSCALEB.S", ++ FSEL: "FSEL", ++ FSQRT_D: "FSQRT.D", ++ FSQRT_S: "FSQRT.S", ++ FSTGT_D: "FSTGT.D", ++ FSTGT_S: "FSTGT.S", ++ FSTLE_D: "FSTLE.D", ++ FSTLE_S: "FSTLE.S", ++ FSTX_D: "FSTX.D", ++ FSTX_S: "FSTX.S", ++ FST_D: "FST.D", ++ FST_S: "FST.S", ++ FSUB_D: "FSUB.D", ++ FSUB_S: "FSUB.S", ++ FTINTRM_L_D: "FTINTRM.L.D", ++ FTINTRM_L_S: "FTINTRM.L.S", ++ FTINTRM_W_D: "FTINTRM.W.D", ++ FTINTRM_W_S: "FTINTRM.W.S", ++ FTINTRNE_L_D: "FTINTRNE.L.D", ++ FTINTRNE_L_S: "FTINTRNE.L.S", ++ FTINTRNE_W_D: "FTINTRNE.W.D", ++ FTINTRNE_W_S: "FTINTRNE.W.S", ++ FTINTRP_L_D: "FTINTRP.L.D", ++ FTINTRP_L_S: "FTINTRP.L.S", ++ FTINTRP_W_D: "FTINTRP.W.D", ++ FTINTRP_W_S: "FTINTRP.W.S", ++ FTINTRZ_L_D: "FTINTRZ.L.D", ++ FTINTRZ_L_S: "FTINTRZ.L.S", ++ FTINTRZ_W_D: "FTINTRZ.W.D", ++ FTINTRZ_W_S: "FTINTRZ.W.S", ++ FTINT_L_D: "FTINT.L.D", ++ FTINT_L_S: "FTINT.L.S", ++ FTINT_W_D: "FTINT.W.D", ++ FTINT_W_S: "FTINT.W.S", ++ IBAR: "IBAR", ++ IDLE: "IDLE", ++ INVTLB: "INVTLB", ++ IOCSRRD_B: "IOCSRRD.B", ++ IOCSRRD_D: "IOCSRRD.D", ++ IOCSRRD_H: "IOCSRRD.H", ++ IOCSRRD_W: "IOCSRRD.W", ++ IOCSRWR_B: "IOCSRWR.B", ++ IOCSRWR_D: "IOCSRWR.D", ++ IOCSRWR_H: "IOCSRWR.H", ++ IOCSRWR_W: "IOCSRWR.W", ++ JIRL: "JIRL", ++ LDDIR: "LDDIR", ++ LDGT_B: "LDGT.B", ++ LDGT_D: "LDGT.D", ++ LDGT_H: "LDGT.H", ++ LDGT_W: "LDGT.W", ++ LDLE_B: "LDLE.B", ++ LDLE_D: "LDLE.D", ++ LDLE_H: "LDLE.H", ++ LDLE_W: "LDLE.W", ++ LDPTE: "LDPTE", ++ LDPTR_D: "LDPTR.D", ++ LDPTR_W: "LDPTR.W", ++ LDX_B: "LDX.B", ++ LDX_BU: "LDX.BU", ++ LDX_D: "LDX.D", ++ LDX_H: "LDX.H", ++ LDX_HU: "LDX.HU", ++ LDX_W: "LDX.W", ++ LDX_WU: "LDX.WU", ++ LD_B: "LD.B", ++ LD_BU: "LD.BU", ++ LD_D: "LD.D", ++ LD_H: "LD.H", ++ LD_HU: "LD.HU", ++ LD_W: "LD.W", ++ LD_WU: "LD.WU", ++ LL_D: "LL.D", ++ LL_W: "LL.W", ++ LU12I_W: "LU12I.W", ++ LU32I_D: "LU32I.D", ++ LU52I_D: "LU52I.D", ++ MASKEQZ: "MASKEQZ", ++ MASKNEZ: "MASKNEZ", ++ MOD_D: "MOD.D", ++ MOD_DU: "MOD.DU", ++ MOD_W: "MOD.W", ++ MOD_WU: "MOD.WU", ++ MOVCF2FR: "MOVCF2FR", ++ MOVCF2GR: "MOVCF2GR", ++ MOVFCSR2GR: "MOVFCSR2GR", ++ MOVFR2CF: "MOVFR2CF", ++ MOVFR2GR_D: "MOVFR2GR.D", ++ MOVFR2GR_S: "MOVFR2GR.S", ++ MOVFRH2GR_S: "MOVFRH2GR.S", ++ MOVGR2CF: "MOVGR2CF", ++ MOVGR2FCSR: "MOVGR2FCSR", ++ MOVGR2FRH_W: "MOVGR2FRH.W", ++ MOVGR2FR_D: "MOVGR2FR.D", ++ MOVGR2FR_W: "MOVGR2FR.W", ++ MULH_D: "MULH.D", ++ MULH_DU: "MULH.DU", ++ MULH_W: "MULH.W", ++ MULH_WU: "MULH.WU", ++ MULW_D_W: "MULW.D.W", ++ MULW_D_WU: "MULW.D.WU", ++ MUL_D: "MUL.D", ++ MUL_W: "MUL.W", ++ NOR: "NOR", ++ OR: "OR", ++ ORI: "ORI", ++ ORN: "ORN", ++ PCADDI: "PCADDI", ++ PCADDU12I: "PCADDU12I", ++ PCADDU18I: "PCADDU18I", ++ PCALAU12I: "PCALAU12I", ++ PRELD: "PRELD", ++ PRELDX: "PRELDX", ++ RDTIMEH_W: "RDTIMEH.W", ++ RDTIMEL_W: "RDTIMEL.W", ++ RDTIME_D: "RDTIME.D", ++ REVB_2H: "REVB.2H", ++ REVB_2W: "REVB.2W", ++ REVB_4H: "REVB.4H", ++ REVB_D: "REVB.D", ++ REVH_2W: "REVH.2W", ++ REVH_D: "REVH.D", ++ ROTRI_D: "ROTRI.D", ++ ROTRI_W: "ROTRI.W", ++ ROTR_D: "ROTR.D", ++ ROTR_W: "ROTR.W", ++ SC_D: "SC.D", ++ SC_W: "SC.W", ++ SLLI_D: "SLLI.D", ++ SLLI_W: "SLLI.W", ++ SLL_D: "SLL.D", ++ SLL_W: "SLL.W", ++ SLT: "SLT", ++ SLTI: "SLTI", ++ SLTU: "SLTU", ++ SLTUI: "SLTUI", ++ SRAI_D: "SRAI.D", ++ SRAI_W: "SRAI.W", ++ SRA_D: "SRA.D", ++ SRA_W: "SRA.W", ++ SRLI_D: "SRLI.D", ++ SRLI_W: "SRLI.W", ++ SRL_D: "SRL.D", ++ SRL_W: "SRL.W", ++ STGT_B: "STGT.B", ++ STGT_D: "STGT.D", ++ STGT_H: "STGT.H", ++ STGT_W: "STGT.W", ++ STLE_B: "STLE.B", ++ STLE_D: "STLE.D", ++ STLE_H: "STLE.H", ++ STLE_W: "STLE.W", ++ STPTR_D: "STPTR.D", ++ STPTR_W: "STPTR.W", ++ STX_B: "STX.B", ++ STX_D: "STX.D", ++ STX_H: "STX.H", ++ STX_W: "STX.W", ++ ST_B: "ST.B", ++ ST_D: "ST.D", ++ ST_H: "ST.H", ++ ST_W: "ST.W", ++ SUB_D: "SUB.D", ++ SUB_W: "SUB.W", ++ SYSCALL: "SYSCALL", ++ TLBCLR: "TLBCLR", ++ TLBFILL: "TLBFILL", ++ TLBFLUSH: "TLBFLUSH", ++ TLBRD: "TLBRD", ++ TLBSRCH: "TLBSRCH", ++ TLBWR: "TLBWR", ++ XOR: "XOR", ++ XORI: "XORI", ++} ++ ++var instFormats = [...]instFormat{ ++ // ADDI.D rd, rj, si12 ++ {mask: 0xffc00000, value: 0x02c00000, op: ADDI_D, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}}, ++ // ADDI.W rd, rj, si12 ++ {mask: 0xffc00000, value: 0x02800000, op: ADDI_W, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}}, ++ // ADDU16I.D rd, rj, si16 ++ {mask: 0xfc000000, value: 0x10000000, op: ADDU16I_D, args: instArgs{arg_rd, arg_rj, arg_si16_25_10}}, ++ // ADD.D rd, rj, rk ++ {mask: 0xffff8000, value: 0x00108000, op: ADD_D, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // ADD.W rd, rj, rk ++ {mask: 0xffff8000, value: 0x00100000, op: ADD_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // ALSL.D rd, rj, rk, sa2 ++ {mask: 0xfffe0000, value: 0x002c0000, op: ALSL_D, args: instArgs{arg_rd, arg_rj, arg_rk, arg_sa2_16_15}}, ++ // ALSL.W rd, rj, rk, sa2 ++ {mask: 0xfffe0000, value: 0x00040000, op: ALSL_W, args: instArgs{arg_rd, arg_rj, arg_rk, arg_sa2_16_15}}, ++ // ALSL.WU rd, rj, rk, sa2 ++ {mask: 0xfffe0000, value: 0x00060000, op: ALSL_WU, args: instArgs{arg_rd, arg_rj, arg_rk, arg_sa2_16_15}}, ++ // AMADD.D rd, rk, rj ++ {mask: 0xffff8000, value: 0x38618000, op: AMADD_D, args: instArgs{arg_rd, arg_rk, arg_rj}}, ++ // AMADD_DB.D rd, rk, rj ++ {mask: 0xffff8000, value: 0x386a8000, op: AMADD_DB_D, args: instArgs{arg_rd, arg_rk, arg_rj}}, ++ // AMADD_DB.W rd, rk, rj ++ {mask: 0xffff8000, value: 0x386a0000, op: AMADD_DB_W, args: instArgs{arg_rd, arg_rk, arg_rj}}, ++ // AMADD.W rd, rk, rj ++ {mask: 0xffff8000, value: 0x38610000, op: AMADD_W, args: instArgs{arg_rd, arg_rk, arg_rj}}, ++ // AMAND.D rd, rk, rj ++ {mask: 0xffff8000, value: 0x38628000, op: AMAND_D, args: instArgs{arg_rd, arg_rk, arg_rj}}, ++ // AMAND_DB.D rd, rk, rj ++ {mask: 0xffff8000, value: 0x386b8000, op: AMAND_DB_D, args: instArgs{arg_rd, arg_rk, arg_rj}}, ++ // AMAND_DB.W rd, rk, rj ++ {mask: 0xffff8000, value: 0x386b0000, op: AMAND_DB_W, args: instArgs{arg_rd, arg_rk, arg_rj}}, ++ // AMAND.W rd, rk, rj ++ {mask: 0xffff8000, value: 0x38620000, op: AMAND_W, args: instArgs{arg_rd, arg_rk, arg_rj}}, ++ // AMMAX.D rd, rk, rj ++ {mask: 0xffff8000, value: 0x38658000, op: AMMAX_D, args: instArgs{arg_rd, arg_rk, arg_rj}}, ++ // AMMAX_DB.D rd, rk, rj ++ {mask: 0xffff8000, value: 0x386e8000, op: AMMAX_DB_D, args: instArgs{arg_rd, arg_rk, arg_rj}}, ++ // AMMAX_DB.DU rd, rk, rj ++ {mask: 0xffff8000, value: 0x38708000, op: AMMAX_DB_DU, args: instArgs{arg_rd, arg_rk, arg_rj}}, ++ // AMMAX_DB.W rd, rk, rj ++ {mask: 0xffff8000, value: 0x386e0000, op: AMMAX_DB_W, args: instArgs{arg_rd, arg_rk, arg_rj}}, ++ // AMMAX_DB.WU rd, rk, rj ++ {mask: 0xffff8000, value: 0x38700000, op: AMMAX_DB_WU, args: instArgs{arg_rd, arg_rk, arg_rj}}, ++ // AMMAX.DU rd, rk, rj ++ {mask: 0xffff8000, value: 0x38678000, op: AMMAX_DU, args: instArgs{arg_rd, arg_rk, arg_rj}}, ++ // AMMAX.W rd, rk, rj ++ {mask: 0xffff8000, value: 0x38650000, op: AMMAX_W, args: instArgs{arg_rd, arg_rk, arg_rj}}, ++ // AMMAX.WU rd, rk, rj ++ {mask: 0xffff8000, value: 0x38670000, op: AMMAX_WU, args: instArgs{arg_rd, arg_rk, arg_rj}}, ++ // AMMIN.D rd, rk, rj ++ {mask: 0xffff8000, value: 0x38668000, op: AMMIN_D, args: instArgs{arg_rd, arg_rk, arg_rj}}, ++ // AMMIN_DB.D rd, rk, rj ++ {mask: 0xffff8000, value: 0x386f8000, op: AMMIN_DB_D, args: instArgs{arg_rd, arg_rk, arg_rj}}, ++ // AMMIN_DB.DU rd, rk, rj ++ {mask: 0xffff8000, value: 0x38718000, op: AMMIN_DB_DU, args: instArgs{arg_rd, arg_rk, arg_rj}}, ++ // AMMIN_DB.W rd, rk, rj ++ {mask: 0xffff8000, value: 0x386f0000, op: AMMIN_DB_W, args: instArgs{arg_rd, arg_rk, arg_rj}}, ++ // AMMIN_DB.WU rd, rk, rj ++ {mask: 0xffff8000, value: 0x38710000, op: AMMIN_DB_WU, args: instArgs{arg_rd, arg_rk, arg_rj}}, ++ // AMMIN.DU rd, rk, rj ++ {mask: 0xffff8000, value: 0x38688000, op: AMMIN_DU, args: instArgs{arg_rd, arg_rk, arg_rj}}, ++ // AMMIN.W rd, rk, rj ++ {mask: 0xffff8000, value: 0x38660000, op: AMMIN_W, args: instArgs{arg_rd, arg_rk, arg_rj}}, ++ // AMMIN.WU rd, rk, rj ++ {mask: 0xffff8000, value: 0x38680000, op: AMMIN_WU, args: instArgs{arg_rd, arg_rk, arg_rj}}, ++ // AMOR.D rd, rk, rj ++ {mask: 0xffff8000, value: 0x38638000, op: AMOR_D, args: instArgs{arg_rd, arg_rk, arg_rj}}, ++ // AMOR_DB.D rd, rk, rj ++ {mask: 0xffff8000, value: 0x386c8000, op: AMOR_DB_D, args: instArgs{arg_rd, arg_rk, arg_rj}}, ++ // AMOR_DB.W rd, rk, rj ++ {mask: 0xffff8000, value: 0x386c0000, op: AMOR_DB_W, args: instArgs{arg_rd, arg_rk, arg_rj}}, ++ // AMOR.W rd, rk, rj ++ {mask: 0xffff8000, value: 0x38630000, op: AMOR_W, args: instArgs{arg_rd, arg_rk, arg_rj}}, ++ // AMSWAP.D rd, rk, rj ++ {mask: 0xffff8000, value: 0x38608000, op: AMSWAP_D, args: instArgs{arg_rd, arg_rk, arg_rj}}, ++ // AMSWAP_DB.D rd, rk, rj ++ {mask: 0xffff8000, value: 0x38698000, op: AMSWAP_DB_D, args: instArgs{arg_rd, arg_rk, arg_rj}}, ++ // AMSWAP_DB.W rd, rk, rj ++ {mask: 0xffff8000, value: 0x38690000, op: AMSWAP_DB_W, args: instArgs{arg_rd, arg_rk, arg_rj}}, ++ // AMSWAP.W rd, rk, rj ++ {mask: 0xffff8000, value: 0x38600000, op: AMSWAP_W, args: instArgs{arg_rd, arg_rk, arg_rj}}, ++ // AMXOR.D rd, rk, rj ++ {mask: 0xffff8000, value: 0x38648000, op: AMXOR_D, args: instArgs{arg_rd, arg_rk, arg_rj}}, ++ // AMXOR_DB.D rd, rk, rj ++ {mask: 0xffff8000, value: 0x386d8000, op: AMXOR_DB_D, args: instArgs{arg_rd, arg_rk, arg_rj}}, ++ // AMXOR_DB.W rd, rk, rj ++ {mask: 0xffff8000, value: 0x386d0000, op: AMXOR_DB_W, args: instArgs{arg_rd, arg_rk, arg_rj}}, ++ // AMXOR.W rd, rk, rj ++ {mask: 0xffff8000, value: 0x38640000, op: AMXOR_W, args: instArgs{arg_rd, arg_rk, arg_rj}}, ++ // AND rd, rj, rk ++ {mask: 0xffff8000, value: 0x00148000, op: AND, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // ANDI rd, rj, ui12 ++ {mask: 0xffc00000, value: 0x03400000, op: ANDI, args: instArgs{arg_rd, arg_rj, arg_ui12_21_10}}, ++ // ANDN rd, rj, rk ++ {mask: 0xffff8000, value: 0x00168000, op: ANDN, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // ASRTGT.D rj, rk ++ {mask: 0xffff801f, value: 0x00018000, op: ASRTGT_D, args: instArgs{arg_rj, arg_rk}}, ++ // ASRTLE.D rj, rk ++ {mask: 0xffff801f, value: 0x00010000, op: ASRTLE_D, args: instArgs{arg_rj, arg_rk}}, ++ // B offs ++ {mask: 0xfc000000, value: 0x50000000, op: B, args: instArgs{arg_offset_25_0}}, ++ // BCEQZ cj, offs ++ {mask: 0xfc000300, value: 0x48000000, op: BCEQZ, args: instArgs{arg_cj, arg_offset_20_0}}, ++ // BCNEZ cj, offs ++ {mask: 0xfc000300, value: 0x48000100, op: BCNEZ, args: instArgs{arg_cj, arg_offset_20_0}}, ++ // BEQ rj, rd, offs ++ {mask: 0xfc000000, value: 0x58000000, op: BEQ, args: instArgs{arg_rj, arg_rd, arg_offset_15_0}}, ++ // BEQZ rj, offs ++ {mask: 0xfc000000, value: 0x40000000, op: BEQZ, args: instArgs{arg_rj, arg_offset_20_0}}, ++ // BGE rj, rd, offs ++ {mask: 0xfc000000, value: 0x64000000, op: BGE, args: instArgs{arg_rj, arg_rd, arg_offset_15_0}}, ++ // BGEU rj, rd, offs ++ {mask: 0xfc000000, value: 0x6c000000, op: BGEU, args: instArgs{arg_rj, arg_rd, arg_offset_15_0}}, ++ // BITREV.4B rd, rj ++ {mask: 0xfffffc00, value: 0x00004800, op: BITREV_4B, args: instArgs{arg_rd, arg_rj}}, ++ // BITREV.8B rd, rj ++ {mask: 0xfffffc00, value: 0x00004c00, op: BITREV_8B, args: instArgs{arg_rd, arg_rj}}, ++ // BITREV.D rd, rj ++ {mask: 0xfffffc00, value: 0x00005400, op: BITREV_D, args: instArgs{arg_rd, arg_rj}}, ++ // BITREV.W rd, rj ++ {mask: 0xfffffc00, value: 0x00005000, op: BITREV_W, args: instArgs{arg_rd, arg_rj}}, ++ // BL offs ++ {mask: 0xfc000000, value: 0x54000000, op: BL, args: instArgs{arg_offset_25_0}}, ++ // BLT rj, rd, offs ++ {mask: 0xfc000000, value: 0x60000000, op: BLT, args: instArgs{arg_rj, arg_rd, arg_offset_15_0}}, ++ // BLTU rj, rd, offs ++ {mask: 0xfc000000, value: 0x68000000, op: BLTU, args: instArgs{arg_rj, arg_rd, arg_offset_15_0}}, ++ // BNE rj, rd, offs ++ {mask: 0xfc000000, value: 0x5c000000, op: BNE, args: instArgs{arg_rj, arg_rd, arg_offset_15_0}}, ++ // BNEZ rj, offs ++ {mask: 0xfc000000, value: 0x44000000, op: BNEZ, args: instArgs{arg_rj, arg_offset_20_0}}, ++ // BREAK code ++ {mask: 0xffff8000, value: 0x002a0000, op: BREAK, args: instArgs{arg_code_14_0}}, ++ // BSTRINS.D rd, rj, msbd, lsbd ++ {mask: 0xffc00000, value: 0x00800000, op: BSTRINS_D, args: instArgs{arg_rd, arg_rj, arg_msbd, arg_lsbd}}, ++ // BSTRINS.W rd, rj, msbw, lsbw ++ {mask: 0xffe08000, value: 0x00600000, op: BSTRINS_W, args: instArgs{arg_rd, arg_rj, arg_msbw, arg_lsbw}}, ++ // BSTRPICK.D rd, rj, msbd, lsbd ++ {mask: 0xffc00000, value: 0x00c00000, op: BSTRPICK_D, args: instArgs{arg_rd, arg_rj, arg_msbd, arg_lsbd}}, ++ // BSTRPICK.W rd, rj, msbw, lsbw ++ {mask: 0xffe08000, value: 0x00608000, op: BSTRPICK_W, args: instArgs{arg_rd, arg_rj, arg_msbw, arg_lsbw}}, ++ // BYTEPICK.D rd, rj, rk, sa3 ++ {mask: 0xfffc0000, value: 0x000c0000, op: BYTEPICK_D, args: instArgs{arg_rd, arg_rj, arg_rk, arg_sa3_17_15}}, ++ // BYTEPICK.W rd, rj, rk, sa2 ++ {mask: 0xfffe0000, value: 0x00080000, op: BYTEPICK_W, args: instArgs{arg_rd, arg_rj, arg_rk, arg_sa2_16_15}}, ++ // CACOP code, rj, si12 ++ {mask: 0xffc00000, value: 0x06000000, op: CACOP, args: instArgs{arg_code_4_0, arg_rj, arg_si12_21_10}}, ++ // CLO.D rd, rj ++ {mask: 0xfffffc00, value: 0x00002000, op: CLO_D, args: instArgs{arg_rd, arg_rj}}, ++ // CLO.W rd, rj ++ {mask: 0xfffffc00, value: 0x00001000, op: CLO_W, args: instArgs{arg_rd, arg_rj}}, ++ // CLZ.D rd, rj ++ {mask: 0xfffffc00, value: 0x00002400, op: CLZ_D, args: instArgs{arg_rd, arg_rj}}, ++ // CLZ.W rd, rj ++ {mask: 0xfffffc00, value: 0x00001400, op: CLZ_W, args: instArgs{arg_rd, arg_rj}}, ++ // CPUCFG rd, rj ++ {mask: 0xfffffc00, value: 0x00006c00, op: CPUCFG, args: instArgs{arg_rd, arg_rj}}, ++ // CRCC.W.B.W rd, rj, rk ++ {mask: 0xffff8000, value: 0x00260000, op: CRCC_W_B_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // CRCC.W.D.W rd, rj, rk ++ {mask: 0xffff8000, value: 0x00278000, op: CRCC_W_D_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // CRCC.W.H.W rd, rj, rk ++ {mask: 0xffff8000, value: 0x00268000, op: CRCC_W_H_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // CRCC.W.W.W rd, rj, rk ++ {mask: 0xffff8000, value: 0x00270000, op: CRCC_W_W_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // CRC.W.B.W rd, rj, rk ++ {mask: 0xffff8000, value: 0x00240000, op: CRC_W_B_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // CRC.W.D.W rd, rj, rk ++ {mask: 0xffff8000, value: 0x00258000, op: CRC_W_D_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // CRC.W.H.W rd, rj, rk ++ {mask: 0xffff8000, value: 0x00248000, op: CRC_W_H_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // CRC.W.W.W rd, rj, rk ++ {mask: 0xffff8000, value: 0x00250000, op: CRC_W_W_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // CSRRD rd, csr ++ {mask: 0xff0003e0, value: 0x04000000, op: CSRRD, args: instArgs{arg_rd, arg_csr_23_10}}, ++ // CSRWR rd, csr ++ {mask: 0xff0003e0, value: 0x04000020, op: CSRWR, args: instArgs{arg_rd, arg_csr_23_10}}, ++ // CSRXCHG rd, rj, csr ++ {mask: 0xff000000, value: 0x04000000, op: CSRXCHG, args: instArgs{arg_rd, arg_rj, arg_csr_23_10}}, ++ // CTO.D rd, rj ++ {mask: 0xfffffc00, value: 0x00002800, op: CTO_D, args: instArgs{arg_rd, arg_rj}}, ++ // CTO.W rd, rj ++ {mask: 0xfffffc00, value: 0x00001800, op: CTO_W, args: instArgs{arg_rd, arg_rj}}, ++ // CTZ.D rd, rj ++ {mask: 0xfffffc00, value: 0x00002c00, op: CTZ_D, args: instArgs{arg_rd, arg_rj}}, ++ // CTZ.W rd, rj ++ {mask: 0xfffffc00, value: 0x00001c00, op: CTZ_W, args: instArgs{arg_rd, arg_rj}}, ++ // DBAR hint ++ {mask: 0xffff8000, value: 0x38720000, op: DBAR, args: instArgs{arg_hint_14_0}}, ++ // DBCL code ++ {mask: 0xffff8000, value: 0x002a8000, op: DBCL, args: instArgs{arg_code_14_0}}, ++ // DIV.D rd, rj, rk ++ {mask: 0xffff8000, value: 0x00220000, op: DIV_D, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // DIV.DU rd, rj, rk ++ {mask: 0xffff8000, value: 0x00230000, op: DIV_DU, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // DIV.W rd, rj, rk ++ {mask: 0xffff8000, value: 0x00200000, op: DIV_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // DIV.WU rd, rj, rk ++ {mask: 0xffff8000, value: 0x00210000, op: DIV_WU, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // ERTN ++ {mask: 0xffffffff, value: 0x06483800, op: ERTN, args: instArgs{}}, ++ // EXT.W.B rd, rj ++ {mask: 0xfffffc00, value: 0x00005c00, op: EXT_W_B, args: instArgs{arg_rd, arg_rj}}, ++ // EXT.W.H rd, rj ++ {mask: 0xfffffc00, value: 0x00005800, op: EXT_W_H, args: instArgs{arg_rd, arg_rj}}, ++ // FABS.D fd, fj ++ {mask: 0xfffffc00, value: 0x01140800, op: FABS_D, args: instArgs{arg_fd, arg_fj}}, ++ // FABS.S fd, fj ++ {mask: 0xfffffc00, value: 0x01140400, op: FABS_S, args: instArgs{arg_fd, arg_fj}}, ++ // FADD.D fd, fj, fk ++ {mask: 0xffff8000, value: 0x01010000, op: FADD_D, args: instArgs{arg_fd, arg_fj, arg_fk}}, ++ // FADD.S fd, fj, fk ++ {mask: 0xffff8000, value: 0x01008000, op: FADD_S, args: instArgs{arg_fd, arg_fj, arg_fk}}, ++ // FCLASS.D fd, fj ++ {mask: 0xfffffc00, value: 0x01143800, op: FCLASS_D, args: instArgs{arg_fd, arg_fj}}, ++ // FCLASS.S fd, fj ++ {mask: 0xfffffc00, value: 0x01143400, op: FCLASS_S, args: instArgs{arg_fd, arg_fj}}, ++ // FCMP.CAF.D cd, fj, fk ++ {mask: 0xffff8018, value: 0x0c200000, op: FCMP_CAF_D, args: instArgs{arg_cd, arg_fj, arg_fk}}, ++ // FCMP.CAF.S cd, fj, fk ++ {mask: 0xffff8018, value: 0x0c100000, op: FCMP_CAF_S, args: instArgs{arg_cd, arg_fj, arg_fk}}, ++ // FCMP.CEQ.D cd, fj, fk ++ {mask: 0xffff8018, value: 0x0c220000, op: FCMP_CEQ_D, args: instArgs{arg_cd, arg_fj, arg_fk}}, ++ // FCMP.CEQ.S cd, fj, fk ++ {mask: 0xffff8018, value: 0x0c120000, op: FCMP_CEQ_S, args: instArgs{arg_cd, arg_fj, arg_fk}}, ++ // FCMP.CLE.D cd, fj, fk ++ {mask: 0xffff8018, value: 0x0c230000, op: FCMP_CLE_D, args: instArgs{arg_cd, arg_fj, arg_fk}}, ++ // FCMP.CLE.S cd, fj, fk ++ {mask: 0xffff8018, value: 0x0c130000, op: FCMP_CLE_S, args: instArgs{arg_cd, arg_fj, arg_fk}}, ++ // FCMP.CLT.D cd, fj, fk ++ {mask: 0xffff8018, value: 0x0c210000, op: FCMP_CLT_D, args: instArgs{arg_cd, arg_fj, arg_fk}}, ++ // FCMP.CLT.S cd, fj, fk ++ {mask: 0xffff8018, value: 0x0c110000, op: FCMP_CLT_S, args: instArgs{arg_cd, arg_fj, arg_fk}}, ++ // FCMP.CNE.D cd, fj, fk ++ {mask: 0xffff8018, value: 0x0c280000, op: FCMP_CNE_D, args: instArgs{arg_cd, arg_fj, arg_fk}}, ++ // FCMP.CNE.S cd, fj, fk ++ {mask: 0xffff8018, value: 0x0c180000, op: FCMP_CNE_S, args: instArgs{arg_cd, arg_fj, arg_fk}}, ++ // FCMP.COR.D cd, fj, fk ++ {mask: 0xffff8018, value: 0x0c2a0000, op: FCMP_COR_D, args: instArgs{arg_cd, arg_fj, arg_fk}}, ++ // FCMP.COR.S cd, fj, fk ++ {mask: 0xffff8018, value: 0x0c1a0000, op: FCMP_COR_S, args: instArgs{arg_cd, arg_fj, arg_fk}}, ++ // FCMP.CUEQ.D cd, fj, fk ++ {mask: 0xffff8018, value: 0x0c260000, op: FCMP_CUEQ_D, args: instArgs{arg_cd, arg_fj, arg_fk}}, ++ // FCMP.CUEQ.S cd, fj, fk ++ {mask: 0xffff8018, value: 0x0c160000, op: FCMP_CUEQ_S, args: instArgs{arg_cd, arg_fj, arg_fk}}, ++ // FCMP.CULE.D cd, fj, fk ++ {mask: 0xffff8018, value: 0x0c270000, op: FCMP_CULE_D, args: instArgs{arg_cd, arg_fj, arg_fk}}, ++ // FCMP.CULE.S cd, fj, fk ++ {mask: 0xffff8018, value: 0x0c170000, op: FCMP_CULE_S, args: instArgs{arg_cd, arg_fj, arg_fk}}, ++ // FCMP.CULT.D cd, fj, fk ++ {mask: 0xffff8018, value: 0x0c250000, op: FCMP_CULT_D, args: instArgs{arg_cd, arg_fj, arg_fk}}, ++ // FCMP.CULT.S cd, fj, fk ++ {mask: 0xffff8018, value: 0x0c150000, op: FCMP_CULT_S, args: instArgs{arg_cd, arg_fj, arg_fk}}, ++ // FCMP.CUNE.D cd, fj, fk ++ {mask: 0xffff8018, value: 0x0c2c0000, op: FCMP_CUNE_D, args: instArgs{arg_cd, arg_fj, arg_fk}}, ++ // FCMP.CUNE.S cd, fj, fk ++ {mask: 0xffff8018, value: 0x0c1c0000, op: FCMP_CUNE_S, args: instArgs{arg_cd, arg_fj, arg_fk}}, ++ // FCMP.CUN.D cd, fj, fk ++ {mask: 0xffff8018, value: 0x0c240000, op: FCMP_CUN_D, args: instArgs{arg_cd, arg_fj, arg_fk}}, ++ // FCMP.CUN.S cd, fj, fk ++ {mask: 0xffff8018, value: 0x0c140000, op: FCMP_CUN_S, args: instArgs{arg_cd, arg_fj, arg_fk}}, ++ // FCMP.SAF.D cd, fj, fk ++ {mask: 0xffff8018, value: 0x0c208000, op: FCMP_SAF_D, args: instArgs{arg_cd, arg_fj, arg_fk}}, ++ // FCMP.SAF.S cd, fj, fk ++ {mask: 0xffff8018, value: 0x0c108000, op: FCMP_SAF_S, args: instArgs{arg_cd, arg_fj, arg_fk}}, ++ // FCMP.SEQ.D cd, fj, fk ++ {mask: 0xffff8018, value: 0x0c228000, op: FCMP_SEQ_D, args: instArgs{arg_cd, arg_fj, arg_fk}}, ++ // FCMP.SEQ.S cd, fj, fk ++ {mask: 0xffff8018, value: 0x0c128000, op: FCMP_SEQ_S, args: instArgs{arg_cd, arg_fj, arg_fk}}, ++ // FCMP.SLE.D cd, fj, fk ++ {mask: 0xffff8018, value: 0x0c238000, op: FCMP_SLE_D, args: instArgs{arg_cd, arg_fj, arg_fk}}, ++ // FCMP.SLE.S cd, fj, fk ++ {mask: 0xffff8018, value: 0x0c138000, op: FCMP_SLE_S, args: instArgs{arg_cd, arg_fj, arg_fk}}, ++ // FCMP.SLT.D cd, fj, fk ++ {mask: 0xffff8018, value: 0x0c218000, op: FCMP_SLT_D, args: instArgs{arg_cd, arg_fj, arg_fk}}, ++ // FCMP.SLT.S cd, fj, fk ++ {mask: 0xffff8018, value: 0x0c118000, op: FCMP_SLT_S, args: instArgs{arg_cd, arg_fj, arg_fk}}, ++ // FCMP.SNE.D cd, fj, fk ++ {mask: 0xffff8018, value: 0x0c288000, op: FCMP_SNE_D, args: instArgs{arg_cd, arg_fj, arg_fk}}, ++ // FCMP.SNE.S cd, fj, fk ++ {mask: 0xffff8018, value: 0x0c188000, op: FCMP_SNE_S, args: instArgs{arg_cd, arg_fj, arg_fk}}, ++ // FCMP.SOR.D cd, fj, fk ++ {mask: 0xffff8018, value: 0x0c2a8000, op: FCMP_SOR_D, args: instArgs{arg_cd, arg_fj, arg_fk}}, ++ // FCMP.SOR.S cd, fj, fk ++ {mask: 0xffff8018, value: 0x0c1a8000, op: FCMP_SOR_S, args: instArgs{arg_cd, arg_fj, arg_fk}}, ++ // FCMP.SUEQ.D cd, fj, fk ++ {mask: 0xffff8018, value: 0x0c268000, op: FCMP_SUEQ_D, args: instArgs{arg_cd, arg_fj, arg_fk}}, ++ // FCMP.SUEQ.S cd, fj, fk ++ {mask: 0xffff8018, value: 0x0c168000, op: FCMP_SUEQ_S, args: instArgs{arg_cd, arg_fj, arg_fk}}, ++ // FCMP.SULE.D cd, fj, fk ++ {mask: 0xffff8018, value: 0x0c278000, op: FCMP_SULE_D, args: instArgs{arg_cd, arg_fj, arg_fk}}, ++ // FCMP.SULE.S cd, fj, fk ++ {mask: 0xffff8018, value: 0x0c178000, op: FCMP_SULE_S, args: instArgs{arg_cd, arg_fj, arg_fk}}, ++ // FCMP.SULT.D cd, fj, fk ++ {mask: 0xffff8018, value: 0x0c258000, op: FCMP_SULT_D, args: instArgs{arg_cd, arg_fj, arg_fk}}, ++ // FCMP.SULT.S cd, fj, fk ++ {mask: 0xffff8018, value: 0x0c158000, op: FCMP_SULT_S, args: instArgs{arg_cd, arg_fj, arg_fk}}, ++ // FCMP.SUNE.D cd, fj, fk ++ {mask: 0xffff8018, value: 0x0c2c8000, op: FCMP_SUNE_D, args: instArgs{arg_cd, arg_fj, arg_fk}}, ++ // FCMP.SUNE.S cd, fj, fk ++ {mask: 0xffff8018, value: 0x0c1c8000, op: FCMP_SUNE_S, args: instArgs{arg_cd, arg_fj, arg_fk}}, ++ // FCMP.SUN.D cd, fj, fk ++ {mask: 0xffff8018, value: 0x0c248000, op: FCMP_SUN_D, args: instArgs{arg_cd, arg_fj, arg_fk}}, ++ // FCMP.SUN.S cd, fj, fk ++ {mask: 0xffff8018, value: 0x0c148000, op: FCMP_SUN_S, args: instArgs{arg_cd, arg_fj, arg_fk}}, ++ // FCOPYSIGN.D fd, fj, fk ++ {mask: 0xffff8000, value: 0x01130000, op: FCOPYSIGN_D, args: instArgs{arg_fd, arg_fj, arg_fk}}, ++ // FCOPYSIGN.S fd, fj, fk ++ {mask: 0xffff8000, value: 0x01128000, op: FCOPYSIGN_S, args: instArgs{arg_fd, arg_fj, arg_fk}}, ++ // FCVT.D.S fd, fj ++ {mask: 0xfffffc00, value: 0x01192400, op: FCVT_D_S, args: instArgs{arg_fd, arg_fj}}, ++ // FCVT.S.D fd, fj ++ {mask: 0xfffffc00, value: 0x01191800, op: FCVT_S_D, args: instArgs{arg_fd, arg_fj}}, ++ // FDIV.D fd, fj, fk ++ {mask: 0xffff8000, value: 0x01070000, op: FDIV_D, args: instArgs{arg_fd, arg_fj, arg_fk}}, ++ // FDIV.S fd, fj, fk ++ {mask: 0xffff8000, value: 0x01068000, op: FDIV_S, args: instArgs{arg_fd, arg_fj, arg_fk}}, ++ // FFINT.D.L fd, fj ++ {mask: 0xfffffc00, value: 0x011d2800, op: FFINT_D_L, args: instArgs{arg_fd, arg_fj}}, ++ // FFINT.D.W fd, fj ++ {mask: 0xfffffc00, value: 0x011d2000, op: FFINT_D_W, args: instArgs{arg_fd, arg_fj}}, ++ // FFINT.S.L fd, fj ++ {mask: 0xfffffc00, value: 0x011d1800, op: FFINT_S_L, args: instArgs{arg_fd, arg_fj}}, ++ // FFINT.S.W fd, fj ++ {mask: 0xfffffc00, value: 0x011d1000, op: FFINT_S_W, args: instArgs{arg_fd, arg_fj}}, ++ // FLDGT.D fd, rj, rk ++ {mask: 0xffff8000, value: 0x38748000, op: FLDGT_D, args: instArgs{arg_fd, arg_rj, arg_rk}}, ++ // FLDGT.S fd, rj, rk ++ {mask: 0xffff8000, value: 0x38740000, op: FLDGT_S, args: instArgs{arg_fd, arg_rj, arg_rk}}, ++ // FLDLE.D fd, rj, rk ++ {mask: 0xffff8000, value: 0x38758000, op: FLDLE_D, args: instArgs{arg_fd, arg_rj, arg_rk}}, ++ // FLDLE.S fd, rj, rk ++ {mask: 0xffff8000, value: 0x38750000, op: FLDLE_S, args: instArgs{arg_fd, arg_rj, arg_rk}}, ++ // FLDX.D fd, rj, rk ++ {mask: 0xffff8000, value: 0x38340000, op: FLDX_D, args: instArgs{arg_fd, arg_rj, arg_rk}}, ++ // FLDX.S fd, rj, rk ++ {mask: 0xffff8000, value: 0x38300000, op: FLDX_S, args: instArgs{arg_fd, arg_rj, arg_rk}}, ++ // FLD.D fd, rj, si12 ++ {mask: 0xffc00000, value: 0x2b800000, op: FLD_D, args: instArgs{arg_fd, arg_rj, arg_si12_21_10}}, ++ // FLD.S fd, rj, si12 ++ {mask: 0xffc00000, value: 0x2b000000, op: FLD_S, args: instArgs{arg_fd, arg_rj, arg_si12_21_10}}, ++ // FLOGB.D fd, fj ++ {mask: 0xfffffc00, value: 0x01142800, op: FLOGB_D, args: instArgs{arg_fd, arg_fj}}, ++ // FLOGB.S fd, fj ++ {mask: 0xfffffc00, value: 0x01142400, op: FLOGB_S, args: instArgs{arg_fd, arg_fj}}, ++ // FMADD.D fd, fj, fk, fa ++ {mask: 0xfff00000, value: 0x08200000, op: FMADD_D, args: instArgs{arg_fd, arg_fj, arg_fk, arg_fa}}, ++ // FMADD.S fd, fj, fk, fa ++ {mask: 0xfff00000, value: 0x08100000, op: FMADD_S, args: instArgs{arg_fd, arg_fj, arg_fk, arg_fa}}, ++ // FMAXA.D fd, fj, fk ++ {mask: 0xffff8000, value: 0x010d0000, op: FMAXA_D, args: instArgs{arg_fd, arg_fj, arg_fk}}, ++ // FMAXA.S fd, fj, fk ++ {mask: 0xffff8000, value: 0x010c8000, op: FMAXA_S, args: instArgs{arg_fd, arg_fj, arg_fk}}, ++ // FMAX.D fd, fj, fk ++ {mask: 0xffff8000, value: 0x01090000, op: FMAX_D, args: instArgs{arg_fd, arg_fj, arg_fk}}, ++ // FMAX.S fd, fj, fk ++ {mask: 0xffff8000, value: 0x01088000, op: FMAX_S, args: instArgs{arg_fd, arg_fj, arg_fk}}, ++ // FMINA.D fd, fj, fk ++ {mask: 0xffff8000, value: 0x010f0000, op: FMINA_D, args: instArgs{arg_fd, arg_fj, arg_fk}}, ++ // FMINA.S fd, fj, fk ++ {mask: 0xffff8000, value: 0x010e8000, op: FMINA_S, args: instArgs{arg_fd, arg_fj, arg_fk}}, ++ // FMIN.D fd, fj, fk ++ {mask: 0xffff8000, value: 0x010b0000, op: FMIN_D, args: instArgs{arg_fd, arg_fj, arg_fk}}, ++ // FMIN.S fd, fj, fk ++ {mask: 0xffff8000, value: 0x010a8000, op: FMIN_S, args: instArgs{arg_fd, arg_fj, arg_fk}}, ++ // FMOV.D fd, fj ++ {mask: 0xfffffc00, value: 0x01149800, op: FMOV_D, args: instArgs{arg_fd, arg_fj}}, ++ // FMOV.S fd, fj ++ {mask: 0xfffffc00, value: 0x01149400, op: FMOV_S, args: instArgs{arg_fd, arg_fj}}, ++ // FMSUB.D fd, fj, fk, fa ++ {mask: 0xfff00000, value: 0x08600000, op: FMSUB_D, args: instArgs{arg_fd, arg_fj, arg_fk, arg_fa}}, ++ // FMSUB.S fd, fj, fk, fa ++ {mask: 0xfff00000, value: 0x08500000, op: FMSUB_S, args: instArgs{arg_fd, arg_fj, arg_fk, arg_fa}}, ++ // FMUL.D fd, fj, fk ++ {mask: 0xffff8000, value: 0x01050000, op: FMUL_D, args: instArgs{arg_fd, arg_fj, arg_fk}}, ++ // FMUL.S fd, fj, fk ++ {mask: 0xffff8000, value: 0x01048000, op: FMUL_S, args: instArgs{arg_fd, arg_fj, arg_fk}}, ++ // FNEG.D fd, fj ++ {mask: 0xfffffc00, value: 0x01141800, op: FNEG_D, args: instArgs{arg_fd, arg_fj}}, ++ // FNEG.S fd, fj ++ {mask: 0xfffffc00, value: 0x01141400, op: FNEG_S, args: instArgs{arg_fd, arg_fj}}, ++ // FNMADD.D fd, fj, fk, fa ++ {mask: 0xfff00000, value: 0x08a00000, op: FNMADD_D, args: instArgs{arg_fd, arg_fj, arg_fk, arg_fa}}, ++ // FNMADD.S fd, fj, fk, fa ++ {mask: 0xfff00000, value: 0x08900000, op: FNMADD_S, args: instArgs{arg_fd, arg_fj, arg_fk, arg_fa}}, ++ // FNMSUB.D fd, fj, fk, fa ++ {mask: 0xfff00000, value: 0x08e00000, op: FNMSUB_D, args: instArgs{arg_fd, arg_fj, arg_fk, arg_fa}}, ++ // FNMSUB.S fd, fj, fk, fa ++ {mask: 0xfff00000, value: 0x08d00000, op: FNMSUB_S, args: instArgs{arg_fd, arg_fj, arg_fk, arg_fa}}, ++ // FRECIP.D fd, fj ++ {mask: 0xfffffc00, value: 0x01145800, op: FRECIP_D, args: instArgs{arg_fd, arg_fj}}, ++ // FRECIP.S fd, fj ++ {mask: 0xfffffc00, value: 0x01145400, op: FRECIP_S, args: instArgs{arg_fd, arg_fj}}, ++ // FRINT.D fd, fj ++ {mask: 0xfffffc00, value: 0x011e4800, op: FRINT_D, args: instArgs{arg_fd, arg_fj}}, ++ // FRINT.S fd, fj ++ {mask: 0xfffffc00, value: 0x011e4400, op: FRINT_S, args: instArgs{arg_fd, arg_fj}}, ++ // FRSQRT.D fd, fj ++ {mask: 0xfffffc00, value: 0x01146800, op: FRSQRT_D, args: instArgs{arg_fd, arg_fj}}, ++ // FRSQRT.S fd, fj ++ {mask: 0xfffffc00, value: 0x01146400, op: FRSQRT_S, args: instArgs{arg_fd, arg_fj}}, ++ // FSCALEB.D fd, fj, fk ++ {mask: 0xffff8000, value: 0x01110000, op: FSCALEB_D, args: instArgs{arg_fd, arg_fj, arg_fk}}, ++ // FSCALEB.S fd, fj, fk ++ {mask: 0xffff8000, value: 0x01108000, op: FSCALEB_S, args: instArgs{arg_fd, arg_fj, arg_fk}}, ++ // FSEL fd, fj, fk, ca ++ {mask: 0xfffc0000, value: 0x0d000000, op: FSEL, args: instArgs{arg_fd, arg_fj, arg_fk, arg_ca}}, ++ // FSQRT.D fd, fj ++ {mask: 0xfffffc00, value: 0x01144800, op: FSQRT_D, args: instArgs{arg_fd, arg_fj}}, ++ // FSQRT.S fd, fj ++ {mask: 0xfffffc00, value: 0x01144400, op: FSQRT_S, args: instArgs{arg_fd, arg_fj}}, ++ // FSTGT.D fd, rj, rk ++ {mask: 0xffff8000, value: 0x38768000, op: FSTGT_D, args: instArgs{arg_fd, arg_rj, arg_rk}}, ++ // FSTGT.S fd, rj, rk ++ {mask: 0xffff8000, value: 0x38760000, op: FSTGT_S, args: instArgs{arg_fd, arg_rj, arg_rk}}, ++ // FSTLE.D fd, rj, rk ++ {mask: 0xffff8000, value: 0x38778000, op: FSTLE_D, args: instArgs{arg_fd, arg_rj, arg_rk}}, ++ // FSTLE.S fd, rj, rk ++ {mask: 0xffff8000, value: 0x38770000, op: FSTLE_S, args: instArgs{arg_fd, arg_rj, arg_rk}}, ++ // FSTX.D fd, rj, rk ++ {mask: 0xffff8000, value: 0x383c0000, op: FSTX_D, args: instArgs{arg_fd, arg_rj, arg_rk}}, ++ // FSTX.S fd, rj, rk ++ {mask: 0xffff8000, value: 0x38380000, op: FSTX_S, args: instArgs{arg_fd, arg_rj, arg_rk}}, ++ // FST.D fd, rj, si12 ++ {mask: 0xffc00000, value: 0x2bc00000, op: FST_D, args: instArgs{arg_fd, arg_rj, arg_si12_21_10}}, ++ // FST.S fd, rj, si12 ++ {mask: 0xffc00000, value: 0x2b400000, op: FST_S, args: instArgs{arg_fd, arg_rj, arg_si12_21_10}}, ++ // FSUB.D fd, fj, fk ++ {mask: 0xffff8000, value: 0x01030000, op: FSUB_D, args: instArgs{arg_fd, arg_fj, arg_fk}}, ++ // FSUB.S fd, fj, fk ++ {mask: 0xffff8000, value: 0x01028000, op: FSUB_S, args: instArgs{arg_fd, arg_fj, arg_fk}}, ++ // FTINTRM.L.D fd, fj ++ {mask: 0xfffffc00, value: 0x011a2800, op: FTINTRM_L_D, args: instArgs{arg_fd, arg_fj}}, ++ // FTINTRM.L.S fd, fj ++ {mask: 0xfffffc00, value: 0x011a2400, op: FTINTRM_L_S, args: instArgs{arg_fd, arg_fj}}, ++ // FTINTRM.W.D fd, fj ++ {mask: 0xfffffc00, value: 0x011a0800, op: FTINTRM_W_D, args: instArgs{arg_fd, arg_fj}}, ++ // FTINTRM.W.S fd, fj ++ {mask: 0xfffffc00, value: 0x011a0400, op: FTINTRM_W_S, args: instArgs{arg_fd, arg_fj}}, ++ // FTINTRNE.L.D fd, fj ++ {mask: 0xfffffc00, value: 0x011ae800, op: FTINTRNE_L_D, args: instArgs{arg_fd, arg_fj}}, ++ // FTINTRNE.L.S fd, fj ++ {mask: 0xfffffc00, value: 0x011ae400, op: FTINTRNE_L_S, args: instArgs{arg_fd, arg_fj}}, ++ // FTINTRNE.W.D fd, fj ++ {mask: 0xfffffc00, value: 0x011ac800, op: FTINTRNE_W_D, args: instArgs{arg_fd, arg_fj}}, ++ // FTINTRNE.W.S fd, fj ++ {mask: 0xfffffc00, value: 0x011ac400, op: FTINTRNE_W_S, args: instArgs{arg_fd, arg_fj}}, ++ // FTINTRP.L.D fd, fj ++ {mask: 0xfffffc00, value: 0x011a6800, op: FTINTRP_L_D, args: instArgs{arg_fd, arg_fj}}, ++ // FTINTRP.L.S fd, fj ++ {mask: 0xfffffc00, value: 0x011a6400, op: FTINTRP_L_S, args: instArgs{arg_fd, arg_fj}}, ++ // FTINTRP.W.D fd, fj ++ {mask: 0xfffffc00, value: 0x011a4800, op: FTINTRP_W_D, args: instArgs{arg_fd, arg_fj}}, ++ // FTINTRP.W.S fd, fj ++ {mask: 0xfffffc00, value: 0x011a4400, op: FTINTRP_W_S, args: instArgs{arg_fd, arg_fj}}, ++ // FTINTRZ.L.D fd, fj ++ {mask: 0xfffffc00, value: 0x011aa800, op: FTINTRZ_L_D, args: instArgs{arg_fd, arg_fj}}, ++ // FTINTRZ.L.S fd, fj ++ {mask: 0xfffffc00, value: 0x011aa400, op: FTINTRZ_L_S, args: instArgs{arg_fd, arg_fj}}, ++ // FTINTRZ.W.D fd, fj ++ {mask: 0xfffffc00, value: 0x011a8800, op: FTINTRZ_W_D, args: instArgs{arg_fd, arg_fj}}, ++ // FTINTRZ.W.S fd, fj ++ {mask: 0xfffffc00, value: 0x011a8400, op: FTINTRZ_W_S, args: instArgs{arg_fd, arg_fj}}, ++ // FTINT.L.D fd, fj ++ {mask: 0xfffffc00, value: 0x011b2800, op: FTINT_L_D, args: instArgs{arg_fd, arg_fj}}, ++ // FTINT.L.S fd, fj ++ {mask: 0xfffffc00, value: 0x011b2400, op: FTINT_L_S, args: instArgs{arg_fd, arg_fj}}, ++ // FTINT.W.D fd, fj ++ {mask: 0xfffffc00, value: 0x011b0800, op: FTINT_W_D, args: instArgs{arg_fd, arg_fj}}, ++ // FTINT.W.S fd, fj ++ {mask: 0xfffffc00, value: 0x011b0400, op: FTINT_W_S, args: instArgs{arg_fd, arg_fj}}, ++ // IBAR hint ++ {mask: 0xffff8000, value: 0x38728000, op: IBAR, args: instArgs{arg_hint_14_0}}, ++ // IDLE level ++ {mask: 0xffff8000, value: 0x06488000, op: IDLE, args: instArgs{arg_level_14_0}}, ++ // INVTLB op, rj, rk ++ {mask: 0xffff8000, value: 0x06498000, op: INVTLB, args: instArgs{arg_op_4_0, arg_rj, arg_rk}}, ++ // IOCSRRD.B rd, rj ++ {mask: 0xfffffc00, value: 0x06480000, op: IOCSRRD_B, args: instArgs{arg_rd, arg_rj}}, ++ // IOCSRRD.D rd, rj ++ {mask: 0xfffffc00, value: 0x06480c00, op: IOCSRRD_D, args: instArgs{arg_rd, arg_rj}}, ++ // IOCSRRD.H rd, rj ++ {mask: 0xfffffc00, value: 0x06480400, op: IOCSRRD_H, args: instArgs{arg_rd, arg_rj}}, ++ // IOCSRRD.W rd, rj ++ {mask: 0xfffffc00, value: 0x06480800, op: IOCSRRD_W, args: instArgs{arg_rd, arg_rj}}, ++ // IOCSRWR.B rd, rj ++ {mask: 0xfffffc00, value: 0x06481000, op: IOCSRWR_B, args: instArgs{arg_rd, arg_rj}}, ++ // IOCSRWR.D rd, rj ++ {mask: 0xfffffc00, value: 0x06481c00, op: IOCSRWR_D, args: instArgs{arg_rd, arg_rj}}, ++ // IOCSRWR.H rd, rj ++ {mask: 0xfffffc00, value: 0x06481400, op: IOCSRWR_H, args: instArgs{arg_rd, arg_rj}}, ++ // IOCSRWR.W rd, rj ++ {mask: 0xfffffc00, value: 0x06481800, op: IOCSRWR_W, args: instArgs{arg_rd, arg_rj}}, ++ // JIRL rd, rj, offs ++ {mask: 0xfc000000, value: 0x4c000000, op: JIRL, args: instArgs{arg_rd, arg_rj, arg_offset_15_0}}, ++ // LDDIR rd, rj, level ++ {mask: 0xfffc0000, value: 0x06400000, op: LDDIR, args: instArgs{arg_rd, arg_rj, arg_level_17_10}}, ++ // LDGT.B rd, rj, rk ++ {mask: 0xffff8000, value: 0x38780000, op: LDGT_B, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // LDGT.D rd, rj, rk ++ {mask: 0xffff8000, value: 0x38798000, op: LDGT_D, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // LDGT.H rd, rj, rk ++ {mask: 0xffff8000, value: 0x38788000, op: LDGT_H, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // LDGT.W rd, rj, rk ++ {mask: 0xffff8000, value: 0x38790000, op: LDGT_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // LDLE.B rd, rj, rk ++ {mask: 0xffff8000, value: 0x387a0000, op: LDLE_B, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // LDLE.D rd, rj, rk ++ {mask: 0xffff8000, value: 0x387b8000, op: LDLE_D, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // LDLE.H rd, rj, rk ++ {mask: 0xffff8000, value: 0x387a8000, op: LDLE_H, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // LDLE.W rd, rj, rk ++ {mask: 0xffff8000, value: 0x387b0000, op: LDLE_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // LDPTE rj, seq ++ {mask: 0xfffc001f, value: 0x06440000, op: LDPTE, args: instArgs{arg_rj, arg_seq_17_10}}, ++ // LDPTR.D rd, rj, si14 ++ {mask: 0xff000000, value: 0x26000000, op: LDPTR_D, args: instArgs{arg_rd, arg_rj, arg_si14_23_10}}, ++ // LDPTR.W rd, rj, si14 ++ {mask: 0xff000000, value: 0x24000000, op: LDPTR_W, args: instArgs{arg_rd, arg_rj, arg_si14_23_10}}, ++ // LDX.B rd, rj, rk ++ {mask: 0xffff8000, value: 0x38000000, op: LDX_B, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // LDX.BU rd, rj, rk ++ {mask: 0xffff8000, value: 0x38200000, op: LDX_BU, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // LDX.D rd, rj, rk ++ {mask: 0xffff8000, value: 0x380c0000, op: LDX_D, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // LDX.H rd, rj, rk ++ {mask: 0xffff8000, value: 0x38040000, op: LDX_H, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // LDX.HU rd, rj, rk ++ {mask: 0xffff8000, value: 0x38240000, op: LDX_HU, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // LDX.W rd, rj, rk ++ {mask: 0xffff8000, value: 0x38080000, op: LDX_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // LDX.WU rd, rj, rk ++ {mask: 0xffff8000, value: 0x38280000, op: LDX_WU, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // LD.B rd, rj, si12 ++ {mask: 0xffc00000, value: 0x28000000, op: LD_B, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}}, ++ // LD.BU rd, rj, si12 ++ {mask: 0xffc00000, value: 0x2a000000, op: LD_BU, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}}, ++ // LD.D rd, rj, si12 ++ {mask: 0xffc00000, value: 0x28c00000, op: LD_D, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}}, ++ // LD.H rd, rj, si12 ++ {mask: 0xffc00000, value: 0x28400000, op: LD_H, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}}, ++ // LD.HU rd, rj, si12 ++ {mask: 0xffc00000, value: 0x2a400000, op: LD_HU, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}}, ++ // LD.W rd, rj, si12 ++ {mask: 0xffc00000, value: 0x28800000, op: LD_W, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}}, ++ // LD.WU rd, rj, si12 ++ {mask: 0xffc00000, value: 0x2a800000, op: LD_WU, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}}, ++ // LL.D rd, rj, si14 ++ {mask: 0xff000000, value: 0x22000000, op: LL_D, args: instArgs{arg_rd, arg_rj, arg_si14_23_10}}, ++ // LL.W rd, rj, si14 ++ {mask: 0xff000000, value: 0x20000000, op: LL_W, args: instArgs{arg_rd, arg_rj, arg_si14_23_10}}, ++ // LU12I.W rd, si20 ++ {mask: 0xfe000000, value: 0x14000000, op: LU12I_W, args: instArgs{arg_rd, arg_si20_24_5}}, ++ // LU32I.D rd, si20 ++ {mask: 0xfe000000, value: 0x16000000, op: LU32I_D, args: instArgs{arg_rd, arg_si20_24_5}}, ++ // LU52I.D rd, rj, si12 ++ {mask: 0xffc00000, value: 0x03000000, op: LU52I_D, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}}, ++ // MASKEQZ rd, rj, rk ++ {mask: 0xffff8000, value: 0x00130000, op: MASKEQZ, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // MASKNEZ rd, rj, rk ++ {mask: 0xffff8000, value: 0x00138000, op: MASKNEZ, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // MOD.D rd, rj, rk ++ {mask: 0xffff8000, value: 0x00228000, op: MOD_D, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // MOD.DU rd, rj, rk ++ {mask: 0xffff8000, value: 0x00238000, op: MOD_DU, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // MOD.W rd, rj, rk ++ {mask: 0xffff8000, value: 0x00208000, op: MOD_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // MOD.WU rd, rj, rk ++ {mask: 0xffff8000, value: 0x00218000, op: MOD_WU, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // MOVCF2FR fd, cj ++ {mask: 0xffffff00, value: 0x0114d400, op: MOVCF2FR, args: instArgs{arg_fd, arg_cj}}, ++ // MOVCF2GR rd, cj ++ {mask: 0xffffff00, value: 0x0114dc00, op: MOVCF2GR, args: instArgs{arg_rd, arg_cj}}, ++ // MOVFCSR2GR rd, fcsr ++ {mask: 0xfffffc00, value: 0x0114c800, op: MOVFCSR2GR, args: instArgs{arg_rd, arg_fcsr_9_5}}, ++ // MOVFR2CF cd, fj ++ {mask: 0xfffffc18, value: 0x0114d000, op: MOVFR2CF, args: instArgs{arg_cd, arg_fj}}, ++ // MOVFR2GR.D rd, fj ++ {mask: 0xfffffc00, value: 0x0114b800, op: MOVFR2GR_D, args: instArgs{arg_rd, arg_fj}}, ++ // MOVFR2GR.S rd, fj ++ {mask: 0xfffffc00, value: 0x0114b400, op: MOVFR2GR_S, args: instArgs{arg_rd, arg_fj}}, ++ // MOVFRH2GR.S rd, fj ++ {mask: 0xfffffc00, value: 0x0114bc00, op: MOVFRH2GR_S, args: instArgs{arg_rd, arg_fj}}, ++ // MOVGR2CF cd, rj ++ {mask: 0xfffffc18, value: 0x0114d800, op: MOVGR2CF, args: instArgs{arg_cd, arg_rj}}, ++ // MOVGR2FCSR fcsr, rj ++ {mask: 0xfffffc00, value: 0x0114c000, op: MOVGR2FCSR, args: instArgs{arg_fcsr_4_0, arg_rj}}, ++ // MOVGR2FRH.W fd, rj ++ {mask: 0xfffffc00, value: 0x0114ac00, op: MOVGR2FRH_W, args: instArgs{arg_fd, arg_rj}}, ++ // MOVGR2FR.D fd, rj ++ {mask: 0xfffffc00, value: 0x0114a800, op: MOVGR2FR_D, args: instArgs{arg_fd, arg_rj}}, ++ // MOVGR2FR.W fd, rj ++ {mask: 0xfffffc00, value: 0x0114a400, op: MOVGR2FR_W, args: instArgs{arg_fd, arg_rj}}, ++ // MULH.D rd, rj, rk ++ {mask: 0xffff8000, value: 0x001e0000, op: MULH_D, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // MULH.DU rd, rj, rk ++ {mask: 0xffff8000, value: 0x001e8000, op: MULH_DU, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // MULH.W rd, rj, rk ++ {mask: 0xffff8000, value: 0x001c8000, op: MULH_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // MULH.WU rd, rj, rk ++ {mask: 0xffff8000, value: 0x001d0000, op: MULH_WU, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // MULW.D.W rd, rj, rk ++ {mask: 0xffff8000, value: 0x001f0000, op: MULW_D_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // MULW.D.WU rd, rj, rk ++ {mask: 0xffff8000, value: 0x001f8000, op: MULW_D_WU, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // MUL.D rd, rj, rk ++ {mask: 0xffff8000, value: 0x001d8000, op: MUL_D, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // MUL.W rd, rj, rk ++ {mask: 0xffff8000, value: 0x001c0000, op: MUL_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // NOR rd, rj, rk ++ {mask: 0xffff8000, value: 0x00140000, op: NOR, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // OR rd, rj, rk ++ {mask: 0xffff8000, value: 0x00150000, op: OR, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // ORI rd, rj, ui12 ++ {mask: 0xffc00000, value: 0x03800000, op: ORI, args: instArgs{arg_rd, arg_rj, arg_ui12_21_10}}, ++ // ORN rd, rj, rk ++ {mask: 0xffff8000, value: 0x00160000, op: ORN, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // PCADDI rd, si20 ++ {mask: 0xfe000000, value: 0x18000000, op: PCADDI, args: instArgs{arg_rd, arg_si20_24_5}}, ++ // PCADDU12I rd, si20 ++ {mask: 0xfe000000, value: 0x1c000000, op: PCADDU12I, args: instArgs{arg_rd, arg_si20_24_5}}, ++ // PCADDU18I rd, si20 ++ {mask: 0xfe000000, value: 0x1e000000, op: PCADDU18I, args: instArgs{arg_rd, arg_si20_24_5}}, ++ // PCALAU12I rd, si20 ++ {mask: 0xfe000000, value: 0x1a000000, op: PCALAU12I, args: instArgs{arg_rd, arg_si20_24_5}}, ++ // PRELD hint, rj, si12 ++ {mask: 0xffc00000, value: 0x2ac00000, op: PRELD, args: instArgs{arg_hint_4_0, arg_rj, arg_si12_21_10}}, ++ // PRELDX hint, rj, rk ++ {mask: 0xffff8000, value: 0x382c0000, op: PRELDX, args: instArgs{arg_hint_4_0, arg_rj, arg_rk}}, ++ // RDTIMEH.W rd, rj ++ {mask: 0xfffffc00, value: 0x00006400, op: RDTIMEH_W, args: instArgs{arg_rd, arg_rj}}, ++ // RDTIMEL.W rd, rj ++ {mask: 0xfffffc00, value: 0x00006000, op: RDTIMEL_W, args: instArgs{arg_rd, arg_rj}}, ++ // RDTIME.D rd, rj ++ {mask: 0xfffffc00, value: 0x00006800, op: RDTIME_D, args: instArgs{arg_rd, arg_rj}}, ++ // REVB.2H rd, rj ++ {mask: 0xfffffc00, value: 0x00003000, op: REVB_2H, args: instArgs{arg_rd, arg_rj}}, ++ // REVB.2W rd, rj ++ {mask: 0xfffffc00, value: 0x00003800, op: REVB_2W, args: instArgs{arg_rd, arg_rj}}, ++ // REVB.4H rd, rj ++ {mask: 0xfffffc00, value: 0x00003400, op: REVB_4H, args: instArgs{arg_rd, arg_rj}}, ++ // REVB.D rd, rj ++ {mask: 0xfffffc00, value: 0x00003c00, op: REVB_D, args: instArgs{arg_rd, arg_rj}}, ++ // REVH.2W rd, rj ++ {mask: 0xfffffc00, value: 0x00004000, op: REVH_2W, args: instArgs{arg_rd, arg_rj}}, ++ // REVH.D rd, rj ++ {mask: 0xfffffc00, value: 0x00004400, op: REVH_D, args: instArgs{arg_rd, arg_rj}}, ++ // ROTRI.D rd, rj, ui6 ++ {mask: 0xffff0000, value: 0x004d0000, op: ROTRI_D, args: instArgs{arg_rd, arg_rj, arg_ui6_15_10}}, ++ // ROTRI.W rd, rj, ui5 ++ {mask: 0xffff8000, value: 0x004c8000, op: ROTRI_W, args: instArgs{arg_rd, arg_rj, arg_ui5_14_10}}, ++ // ROTR.D rd, rj, rk ++ {mask: 0xffff8000, value: 0x001b8000, op: ROTR_D, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // ROTR.W rd, rj, rk ++ {mask: 0xffff8000, value: 0x001b0000, op: ROTR_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // SC.D rd, rj, si14 ++ {mask: 0xff000000, value: 0x23000000, op: SC_D, args: instArgs{arg_rd, arg_rj, arg_si14_23_10}}, ++ // SC.W rd, rj, si14 ++ {mask: 0xff000000, value: 0x21000000, op: SC_W, args: instArgs{arg_rd, arg_rj, arg_si14_23_10}}, ++ // SLLI.D rd, rj, ui6 ++ {mask: 0xffff0000, value: 0x00410000, op: SLLI_D, args: instArgs{arg_rd, arg_rj, arg_ui6_15_10}}, ++ // SLLI.W rd, rj, ui5 ++ {mask: 0xffff8000, value: 0x00408000, op: SLLI_W, args: instArgs{arg_rd, arg_rj, arg_ui5_14_10}}, ++ // SLL.D rd, rj, rk ++ {mask: 0xffff8000, value: 0x00188000, op: SLL_D, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // SLL.W rd, rj, rk ++ {mask: 0xffff8000, value: 0x00170000, op: SLL_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // SLT rd, rj, rk ++ {mask: 0xffff8000, value: 0x00120000, op: SLT, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // SLTI rd, rj, si12 ++ {mask: 0xffc00000, value: 0x02000000, op: SLTI, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}}, ++ // SLTU rd, rj, rk ++ {mask: 0xffff8000, value: 0x00128000, op: SLTU, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // SLTUI rd, rj, si12 ++ {mask: 0xffc00000, value: 0x02400000, op: SLTUI, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}}, ++ // SRAI.D rd, rj, ui6 ++ {mask: 0xffff0000, value: 0x00490000, op: SRAI_D, args: instArgs{arg_rd, arg_rj, arg_ui6_15_10}}, ++ // SRAI.W rd, rj, ui5 ++ {mask: 0xffff8000, value: 0x00488000, op: SRAI_W, args: instArgs{arg_rd, arg_rj, arg_ui5_14_10}}, ++ // SRA.D rd, rj, rk ++ {mask: 0xffff8000, value: 0x00198000, op: SRA_D, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // SRA.W rd, rj, rk ++ {mask: 0xffff8000, value: 0x00180000, op: SRA_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // SRLI.D rd, rj, ui6 ++ {mask: 0xffff0000, value: 0x00450000, op: SRLI_D, args: instArgs{arg_rd, arg_rj, arg_ui6_15_10}}, ++ // SRLI.W rd, rj, ui5 ++ {mask: 0xffff8000, value: 0x00448000, op: SRLI_W, args: instArgs{arg_rd, arg_rj, arg_ui5_14_10}}, ++ // SRL.D rd, rj, rk ++ {mask: 0xffff8000, value: 0x00190000, op: SRL_D, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // SRL.W rd, rj, rk ++ {mask: 0xffff8000, value: 0x00178000, op: SRL_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // STGT.B rd, rj, rk ++ {mask: 0xffff8000, value: 0x387c0000, op: STGT_B, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // STGT.D rd, rj, rk ++ {mask: 0xffff8000, value: 0x387d8000, op: STGT_D, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // STGT.H rd, rj, rk ++ {mask: 0xffff8000, value: 0x387c8000, op: STGT_H, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // STGT.W rd, rj, rk ++ {mask: 0xffff8000, value: 0x387d0000, op: STGT_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // STLE.B rd, rj, rk ++ {mask: 0xffff8000, value: 0x387e0000, op: STLE_B, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // STLE.D rd, rj, rk ++ {mask: 0xffff8000, value: 0x387f8000, op: STLE_D, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // STLE.H rd, rj, rk ++ {mask: 0xffff8000, value: 0x387e8000, op: STLE_H, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // STLE.W rd, rj, rk ++ {mask: 0xffff8000, value: 0x387f0000, op: STLE_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // STPTR.D rd, rj, si14 ++ {mask: 0xff000000, value: 0x27000000, op: STPTR_D, args: instArgs{arg_rd, arg_rj, arg_si14_23_10}}, ++ // STPTR.W rd, rj, si14 ++ {mask: 0xff000000, value: 0x25000000, op: STPTR_W, args: instArgs{arg_rd, arg_rj, arg_si14_23_10}}, ++ // STX.B rd, rj, rk ++ {mask: 0xffff8000, value: 0x38100000, op: STX_B, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // STX.D rd, rj, rk ++ {mask: 0xffff8000, value: 0x381c0000, op: STX_D, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // STX.H rd, rj, rk ++ {mask: 0xffff8000, value: 0x38140000, op: STX_H, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // STX.W rd, rj, rk ++ {mask: 0xffff8000, value: 0x38180000, op: STX_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // ST.B rd, rj, si12 ++ {mask: 0xffc00000, value: 0x29000000, op: ST_B, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}}, ++ // ST.D rd, rj, si12 ++ {mask: 0xffc00000, value: 0x29c00000, op: ST_D, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}}, ++ // ST.H rd, rj, si12 ++ {mask: 0xffc00000, value: 0x29400000, op: ST_H, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}}, ++ // ST.W rd, rj, si12 ++ {mask: 0xffc00000, value: 0x29800000, op: ST_W, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}}, ++ // SUB.D rd, rj, rk ++ {mask: 0xffff8000, value: 0x00118000, op: SUB_D, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // SUB.W rd, rj, rk ++ {mask: 0xffff8000, value: 0x00110000, op: SUB_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // SYSCALL code ++ {mask: 0xffff8000, value: 0x002b0000, op: SYSCALL, args: instArgs{arg_code_14_0}}, ++ // TLBCLR ++ {mask: 0xffffffff, value: 0x06482000, op: TLBCLR, args: instArgs{}}, ++ // TLBFILL ++ {mask: 0xffffffff, value: 0x06483400, op: TLBFILL, args: instArgs{}}, ++ // TLBFLUSH ++ {mask: 0xffffffff, value: 0x06482400, op: TLBFLUSH, args: instArgs{}}, ++ // TLBRD ++ {mask: 0xffffffff, value: 0x06482c00, op: TLBRD, args: instArgs{}}, ++ // TLBSRCH ++ {mask: 0xffffffff, value: 0x06482800, op: TLBSRCH, args: instArgs{}}, ++ // TLBWR ++ {mask: 0xffffffff, value: 0x06483000, op: TLBWR, args: instArgs{}}, ++ // XOR rd, rj, rk ++ {mask: 0xffff8000, value: 0x00158000, op: XOR, args: instArgs{arg_rd, arg_rj, arg_rk}}, ++ // XORI rd, rj, ui12 ++ {mask: 0xffc00000, value: 0x03c00000, op: XORI, args: instArgs{arg_rd, arg_rj, arg_ui12_21_10}}, ++} +-- +2.20.1 + diff --git a/loongarch64/0006-cmd-internal-objfile-add-loong64-disassembler-suppor.patch b/loongarch64/0006-cmd-internal-objfile-add-loong64-disassembler-suppor.patch new file mode 100644 index 0000000000000000000000000000000000000000..38c67f4934dabea7f266f88c35d4811310b7f2f2 --- /dev/null +++ b/loongarch64/0006-cmd-internal-objfile-add-loong64-disassembler-suppor.patch @@ -0,0 +1,73 @@ +From a126f01fb5e29f73d97428bc1da0d362d977158f Mon Sep 17 00:00:00 2001 +From: chenguoqi +Date: Fri, 10 Feb 2023 15:10:48 +0800 +Subject: [PATCH 06/51] cmd/internal/objfile: add loong64 disassembler support + +Change-Id: Id29c2de9e592a07a9f932a4aa3718c6b25788082 +--- + src/cmd/internal/objfile/disasm.go | 14 ++++++++++++++ + src/cmd/internal/objfile/elf.go | 2 ++ + 2 files changed, 16 insertions(+) + +diff --git a/src/cmd/internal/objfile/disasm.go b/src/cmd/internal/objfile/disasm.go +index c298d7e1a9..129741fe01 100644 +--- a/src/cmd/internal/objfile/disasm.go ++++ b/src/cmd/internal/objfile/disasm.go +@@ -23,6 +23,7 @@ import ( + + "golang.org/x/arch/arm/armasm" + "golang.org/x/arch/arm64/arm64asm" ++ "golang.org/x/arch/loong64/loong64asm" + "golang.org/x/arch/ppc64/ppc64asm" + "golang.org/x/arch/x86/x86asm" + ) +@@ -366,6 +367,17 @@ func disasm_arm64(code []byte, pc uint64, lookup lookupFunc, byteOrder binary.By + return text, 4 + } + ++func disasm_loong64(code []byte, pc uint64, lookup lookupFunc, byteOrder binary.ByteOrder, gnuAsm bool) (string, int) { ++ inst, err := loong64asm.Decode(code) ++ var text string ++ if err != nil || inst.Op == 0 { ++ text = "?" ++ } else if gnuAsm { ++ text = fmt.Sprintf("%s %s", "", loong64asm.GNUSyntax(inst)) ++ } ++ return text, 4 ++} ++ + func disasm_ppc64(code []byte, pc uint64, lookup lookupFunc, byteOrder binary.ByteOrder, gnuAsm bool) (string, int) { + inst, err := ppc64asm.Decode(code, byteOrder) + var text string +@@ -388,6 +400,7 @@ var disasms = map[string]disasmFunc{ + "amd64": disasm_amd64, + "arm": disasm_arm, + "arm64": disasm_arm64, ++ "loong64": disasm_loong64, + "ppc64": disasm_ppc64, + "ppc64le": disasm_ppc64, + } +@@ -397,6 +410,7 @@ var byteOrders = map[string]binary.ByteOrder{ + "amd64": binary.LittleEndian, + "arm": binary.LittleEndian, + "arm64": binary.LittleEndian, ++ "loong64": binary.LittleEndian, + "ppc64": binary.BigEndian, + "ppc64le": binary.LittleEndian, + "s390x": binary.BigEndian, +diff --git a/src/cmd/internal/objfile/elf.go b/src/cmd/internal/objfile/elf.go +index f25e4a65d6..9048be7d73 100644 +--- a/src/cmd/internal/objfile/elf.go ++++ b/src/cmd/internal/objfile/elf.go +@@ -120,6 +120,8 @@ func (f *elfFile) goarch() string { + return "arm" + case elf.EM_AARCH64: + return "arm64" ++ case elf.EM_LOONGARCH: ++ return "loong64" + case elf.EM_PPC64: + if f.elf.ByteOrder == binary.LittleEndian { + return "ppc64le" +-- +2.20.1 + diff --git a/loongarch64/0007-runtime-remove-the-meaningless-offset-of-8-for-duffz.patch b/loongarch64/0007-runtime-remove-the-meaningless-offset-of-8-for-duffz.patch new file mode 100644 index 0000000000000000000000000000000000000000..913fd30690c8da2e067309ab7f57afe75ac749f3 --- /dev/null +++ b/loongarch64/0007-runtime-remove-the-meaningless-offset-of-8-for-duffz.patch @@ -0,0 +1,542 @@ +From 58fadbe4437f7d458efff12c727f43bca123b0f2 Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Fri, 21 Apr 2023 11:08:09 +0800 +Subject: [PATCH 07/51] runtime: remove the meaningless offset of 8 for + duffzero on loong64 + +Currently we subtract 8 from offset when calling duffzero because 8 +is added to offset in the duffzero implementation. This operation is +meaningless, so remove it. + +Change-Id: I22da26e19353275a9bfae523a9e37f8e4ec26041 +--- + src/cmd/compile/internal/loong64/ggen.go | 23 +- + src/cmd/compile/internal/loong64/ssa.go | 10 +- + .../compile/internal/ssa/_gen/LOONG64Ops.go | 2 +- + src/cmd/compile/internal/ssa/opGen.go | 2 +- + src/runtime/duff_loong64.s | 256 +++++++++--------- + src/runtime/mkduff.go | 4 +- + 6 files changed, 148 insertions(+), 149 deletions(-) + +diff --git a/src/cmd/compile/internal/loong64/ggen.go b/src/cmd/compile/internal/loong64/ggen.go +index 8a24d2f295..27d318a8bb 100644 +--- a/src/cmd/compile/internal/loong64/ggen.go ++++ b/src/cmd/compile/internal/loong64/ggen.go +@@ -5,6 +5,7 @@ + package loong64 + + import ( ++ "cmd/compile/internal/base" + "cmd/compile/internal/ir" + "cmd/compile/internal/objw" + "cmd/compile/internal/types" +@@ -16,34 +17,38 @@ func zerorange(pp *objw.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog + if cnt == 0 { + return p + } ++ ++ // Adjust the frame to account for LR. ++ off += base.Ctxt.Arch.FixedFrameSize ++ + if cnt < int64(4*types.PtrSize) { + for i := int64(0); i < cnt; i += int64(types.PtrSize) { +- p = pp.Append(p, loong64.AMOVV, obj.TYPE_REG, loong64.REGZERO, 0, obj.TYPE_MEM, loong64.REGSP, 8+off+i) ++ p = pp.Append(p, loong64.AMOVV, obj.TYPE_REG, loong64.REGZERO, 0, obj.TYPE_MEM, loong64.REGSP, off+i) + } + } else if cnt <= int64(128*types.PtrSize) { +- p = pp.Append(p, loong64.AADDV, obj.TYPE_CONST, 0, 8+off-8, obj.TYPE_REG, loong64.REGRT1, 0) ++ p = pp.Append(p, loong64.AADDV, obj.TYPE_CONST, 0, off, obj.TYPE_REG, loong64.REGRT1, 0) + p.Reg = loong64.REGSP + p = pp.Append(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_MEM, 0, 0) + p.To.Name = obj.NAME_EXTERN + p.To.Sym = ir.Syms.Duffzero + p.To.Offset = 8 * (128 - cnt/int64(types.PtrSize)) + } else { +- // ADDV $(8+frame+lo-8), SP, r1 ++ // ADDV $(off), SP, r1 + // ADDV $cnt, r1, r2 + // loop: +- // MOVV R0, (Widthptr)r1 ++ // MOVV R0, (r1) + // ADDV $Widthptr, r1 +- // BNE r1, r2, loop +- p = pp.Append(p, loong64.AADDV, obj.TYPE_CONST, 0, 8+off-8, obj.TYPE_REG, loong64.REGRT1, 0) ++ // BNE r1, r2, loop ++ p = pp.Append(p, loong64.AADDV, obj.TYPE_CONST, 0, off, obj.TYPE_REG, loong64.REGRT1, 0) + p.Reg = loong64.REGSP + p = pp.Append(p, loong64.AADDV, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, loong64.REGRT2, 0) + p.Reg = loong64.REGRT1 +- p = pp.Append(p, loong64.AMOVV, obj.TYPE_REG, loong64.REGZERO, 0, obj.TYPE_MEM, loong64.REGRT1, int64(types.PtrSize)) +- p1 := p ++ p = pp.Append(p, loong64.AMOVV, obj.TYPE_REG, loong64.REGZERO, 0, obj.TYPE_MEM, loong64.REGRT1, 0) ++ loop := p + p = pp.Append(p, loong64.AADDV, obj.TYPE_CONST, 0, int64(types.PtrSize), obj.TYPE_REG, loong64.REGRT1, 0) + p = pp.Append(p, loong64.ABNE, obj.TYPE_REG, loong64.REGRT1, 0, obj.TYPE_BRANCH, 0, 0) + p.Reg = loong64.REGRT2 +- p.To.SetTarget(p1) ++ p.To.SetTarget(loop) + } + + return p +diff --git a/src/cmd/compile/internal/loong64/ssa.go b/src/cmd/compile/internal/loong64/ssa.go +index 8193b4e321..574217fd92 100644 +--- a/src/cmd/compile/internal/loong64/ssa.go ++++ b/src/cmd/compile/internal/loong64/ssa.go +@@ -340,14 +340,8 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) { + p.To.Type = obj.TYPE_REG + p.To.Reg = v.Reg() + case ssa.OpLOONG64DUFFZERO: +- // runtime.duffzero expects start address - 8 in R19 +- p := s.Prog(loong64.ASUBVU) +- p.From.Type = obj.TYPE_CONST +- p.From.Offset = 8 +- p.Reg = v.Args[0].Reg() +- p.To.Type = obj.TYPE_REG +- p.To.Reg = loong64.REG_R19 +- p = s.Prog(obj.ADUFFZERO) ++ // runtime.duffzero expects start address in R19 ++ p := s.Prog(obj.ADUFFZERO) + p.To.Type = obj.TYPE_MEM + p.To.Name = obj.NAME_EXTERN + p.To.Sym = ir.Syms.Duffzero +diff --git a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go +index 23f20fddeb..b715b36542 100644 +--- a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go ++++ b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go +@@ -289,7 +289,7 @@ func init() { + aux: "Int64", + argLength: 2, + reg: regInfo{ +- inputs: []regMask{gp}, ++ inputs: []regMask{buildReg("R19")}, + clobbers: buildReg("R19 R1"), + }, + faultOnNilArg0: true, +diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go +index e7caf9050c..e95cb250d9 100644 +--- a/src/cmd/compile/internal/ssa/opGen.go ++++ b/src/cmd/compile/internal/ssa/opGen.go +@@ -24266,7 +24266,7 @@ var opcodeTable = [...]opInfo{ + faultOnNilArg0: true, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 262144}, // R19 + }, + clobbers: 262146, // R1 R19 + }, +diff --git a/src/runtime/duff_loong64.s b/src/runtime/duff_loong64.s +index 7f78e4fa9f..63fa3bcca1 100644 +--- a/src/runtime/duff_loong64.s ++++ b/src/runtime/duff_loong64.s +@@ -5,261 +5,261 @@ + #include "textflag.h" + + TEXT runtime·duffzero(SB), NOSPLIT|NOFRAME, $0-0 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 +- MOVV R0, 8(R19) ++ MOVV R0, (R19) + ADDV $8, R19 + RET + +diff --git a/src/runtime/mkduff.go b/src/runtime/mkduff.go +index cc58558a56..e8d4fcc93e 100644 +--- a/src/runtime/mkduff.go ++++ b/src/runtime/mkduff.go +@@ -179,11 +179,11 @@ func copyARM64(w io.Writer) { + + func zeroLOONG64(w io.Writer) { + // R0: always zero +- // R19 (aka REGRT1): ptr to memory to be zeroed - 8 ++ // R19 (aka REGRT1): ptr to memory to be zeroed + // On return, R19 points to the last zeroed dword. + fmt.Fprintln(w, "TEXT runtime·duffzero(SB), NOSPLIT|NOFRAME, $0-0") + for i := 0; i < 128; i++ { +- fmt.Fprintln(w, "\tMOVV\tR0, 8(R19)") ++ fmt.Fprintln(w, "\tMOVV\tR0, (R19)") + fmt.Fprintln(w, "\tADDV\t$8, R19") + } + fmt.Fprintln(w, "\tRET") +-- +2.20.1 + diff --git a/loongarch64/0008-cmd-compiler-remove-the-meaningless-offset-of-8-for-.patch b/loongarch64/0008-cmd-compiler-remove-the-meaningless-offset-of-8-for-.patch new file mode 100644 index 0000000000000000000000000000000000000000..3634335e37d1fc7d2b253731754da6aeb3977d0e --- /dev/null +++ b/loongarch64/0008-cmd-compiler-remove-the-meaningless-offset-of-8-for-.patch @@ -0,0 +1,312 @@ +From 8ffad50c7e2fa6acd23aba874786cfac7faf6c35 Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Tue, 25 Apr 2023 03:27:23 +0800 +Subject: [PATCH 08/51] cmd/compiler: remove the meaningless offset of 8 for + Lowered{Zero,Move} on loong64 + +Like the CL 487295, remove the meaningless +/- offset operation in the +LoweredZero and LoweredMove implementation. + +Change LoweredMove's Rarg0 register to R20, consistent with duffcopy. + +Change-Id: I19203c428ab25e7ecf657e2ea8ebb0bca77f49ee +--- + src/cmd/compile/internal/loong64/ssa.go | 168 ++++++++---------- + .../compile/internal/ssa/_gen/LOONG64Ops.go | 28 ++- + src/cmd/compile/internal/ssa/opGen.go | 6 +- + 3 files changed, 91 insertions(+), 111 deletions(-) + +diff --git a/src/cmd/compile/internal/loong64/ssa.go b/src/cmd/compile/internal/loong64/ssa.go +index 574217fd92..f74f90fb5f 100644 +--- a/src/cmd/compile/internal/loong64/ssa.go ++++ b/src/cmd/compile/internal/loong64/ssa.go +@@ -80,6 +80,28 @@ func storeByType(t *types.Type, r int16) obj.As { + panic("bad store type") + } + ++// largestMove returns the largest move instruction possible and its size, ++// given the alignment of the total size of the move. ++// ++// e.g., a 16-byte move may use MOVV, but an 11-byte move must use MOVB. ++// ++// Note that the moves may not be on naturally aligned addresses depending on ++// the source and destination. ++// ++// This matches the calculation in ssa.moveSize. ++func largestMove(alignment int64) (obj.As, int64) { ++ switch { ++ case alignment%8 == 0: ++ return loong64.AMOVV, 8 ++ case alignment%4 == 0: ++ return loong64.AMOVW, 4 ++ case alignment%2 == 0: ++ return loong64.AMOVH, 2 ++ default: ++ return loong64.AMOVB, 1 ++ } ++} ++ + func ssaGenValue(s *ssagen.State, v *ssa.Value) { + switch v.Op { + case ssa.OpCopy, ssa.OpLOONG64MOVVreg: +@@ -347,49 +369,29 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) { + p.To.Sym = ir.Syms.Duffzero + p.To.Offset = v.AuxInt + case ssa.OpLOONG64LoweredZero: +- // SUBV $8, R19 +- // MOVV R0, 8(R19) +- // ADDV $8, R19 +- // BNE Rarg1, R19, -2(PC) +- // arg1 is the address of the last element to zero +- var sz int64 +- var mov obj.As +- switch { +- case v.AuxInt%8 == 0: +- sz = 8 +- mov = loong64.AMOVV +- case v.AuxInt%4 == 0: +- sz = 4 +- mov = loong64.AMOVW +- case v.AuxInt%2 == 0: +- sz = 2 +- mov = loong64.AMOVH +- default: +- sz = 1 +- mov = loong64.AMOVB +- } +- p := s.Prog(loong64.ASUBVU) +- p.From.Type = obj.TYPE_CONST +- p.From.Offset = sz +- p.To.Type = obj.TYPE_REG +- p.To.Reg = loong64.REG_R19 +- p2 := s.Prog(mov) +- p2.From.Type = obj.TYPE_REG +- p2.From.Reg = loong64.REGZERO +- p2.To.Type = obj.TYPE_MEM +- p2.To.Reg = loong64.REG_R19 +- p2.To.Offset = sz +- p3 := s.Prog(loong64.AADDVU) +- p3.From.Type = obj.TYPE_CONST +- p3.From.Offset = sz +- p3.To.Type = obj.TYPE_REG +- p3.To.Reg = loong64.REG_R19 +- p4 := s.Prog(loong64.ABNE) +- p4.From.Type = obj.TYPE_REG +- p4.From.Reg = v.Args[1].Reg() +- p4.Reg = loong64.REG_R19 +- p4.To.Type = obj.TYPE_BRANCH +- p4.To.SetTarget(p2) ++ // MOVx R0, (Rarg0) ++ // ADDV $sz, Rarg0 ++ // BGEU Rarg1, Rarg0, -2(PC) ++ mov, sz := largestMove(v.AuxInt) ++ p := s.Prog(mov) ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = loong64.REGZERO ++ p.To.Type = obj.TYPE_MEM ++ p.To.Reg = v.Args[0].Reg() ++ ++ p2 := s.Prog(loong64.AADDVU) ++ p2.From.Type = obj.TYPE_CONST ++ p2.From.Offset = sz ++ p2.To.Type = obj.TYPE_REG ++ p2.To.Reg = v.Args[0].Reg() ++ ++ p3 := s.Prog(loong64.ABGEU) ++ p3.From.Type = obj.TYPE_REG ++ p3.From.Reg = v.Args[1].Reg() ++ p3.Reg = v.Args[0].Reg() ++ p3.To.Type = obj.TYPE_BRANCH ++ p3.To.SetTarget(p) ++ + case ssa.OpLOONG64DUFFCOPY: + p := s.Prog(obj.ADUFFCOPY) + p.To.Type = obj.TYPE_MEM +@@ -397,61 +399,43 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) { + p.To.Sym = ir.Syms.Duffcopy + p.To.Offset = v.AuxInt + case ssa.OpLOONG64LoweredMove: +- // SUBV $8, R19 +- // MOVV 8(R19), Rtmp +- // MOVV Rtmp, (R4) +- // ADDV $8, R19 +- // ADDV $8, R4 +- // BNE Rarg2, R19, -4(PC) +- // arg2 is the address of the last element of src +- var sz int64 +- var mov obj.As +- switch { +- case v.AuxInt%8 == 0: +- sz = 8 +- mov = loong64.AMOVV +- case v.AuxInt%4 == 0: +- sz = 4 +- mov = loong64.AMOVW +- case v.AuxInt%2 == 0: +- sz = 2 +- mov = loong64.AMOVH +- default: +- sz = 1 +- mov = loong64.AMOVB +- } +- p := s.Prog(loong64.ASUBVU) +- p.From.Type = obj.TYPE_CONST +- p.From.Offset = sz ++ // MOVx (Rarg1), Rtmp ++ // MOVx Rtmp, (Rarg0) ++ // ADDV $sz, Rarg1 ++ // ADDV $sz, Rarg0 ++ // BGEU Rarg2, Rarg0, -4(PC) ++ mov, sz := largestMove(v.AuxInt) ++ p := s.Prog(mov) ++ p.From.Type = obj.TYPE_MEM ++ p.From.Reg = v.Args[1].Reg() + p.To.Type = obj.TYPE_REG +- p.To.Reg = loong64.REG_R19 ++ p.To.Reg = loong64.REGTMP ++ + p2 := s.Prog(mov) +- p2.From.Type = obj.TYPE_MEM +- p2.From.Reg = loong64.REG_R19 +- p2.From.Offset = sz +- p2.To.Type = obj.TYPE_REG +- p2.To.Reg = loong64.REGTMP +- p3 := s.Prog(mov) +- p3.From.Type = obj.TYPE_REG +- p3.From.Reg = loong64.REGTMP +- p3.To.Type = obj.TYPE_MEM +- p3.To.Reg = loong64.REG_R4 ++ p2.From.Type = obj.TYPE_REG ++ p2.From.Reg = loong64.REGTMP ++ p2.To.Type = obj.TYPE_MEM ++ p2.To.Reg = v.Args[0].Reg() ++ ++ p3 := s.Prog(loong64.AADDVU) ++ p3.From.Type = obj.TYPE_CONST ++ p3.From.Offset = sz ++ p3.To.Type = obj.TYPE_REG ++ p3.To.Reg = v.Args[1].Reg() ++ + p4 := s.Prog(loong64.AADDVU) + p4.From.Type = obj.TYPE_CONST + p4.From.Offset = sz + p4.To.Type = obj.TYPE_REG +- p4.To.Reg = loong64.REG_R19 +- p5 := s.Prog(loong64.AADDVU) +- p5.From.Type = obj.TYPE_CONST +- p5.From.Offset = sz +- p5.To.Type = obj.TYPE_REG +- p5.To.Reg = loong64.REG_R4 +- p6 := s.Prog(loong64.ABNE) +- p6.From.Type = obj.TYPE_REG +- p6.From.Reg = v.Args[2].Reg() +- p6.Reg = loong64.REG_R19 +- p6.To.Type = obj.TYPE_BRANCH +- p6.To.SetTarget(p2) ++ p4.To.Reg = v.Args[0].Reg() ++ ++ p5 := s.Prog(loong64.ABGEU) ++ p5.From.Type = obj.TYPE_REG ++ p5.From.Reg = v.Args[2].Reg() ++ p5.Reg = v.Args[1].Reg() ++ p5.To.Type = obj.TYPE_BRANCH ++ p5.To.SetTarget(p) ++ + case ssa.OpLOONG64CALLstatic, ssa.OpLOONG64CALLclosure, ssa.OpLOONG64CALLinter: + s.Call(v) + case ssa.OpLOONG64CALLtail: +diff --git a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go +index b715b36542..cb058f45c0 100644 +--- a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go ++++ b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go +@@ -319,10 +319,9 @@ func init() { + // arg2 = mem + // auxint = alignment + // returns mem +- // SUBV $8, R19 +- // MOVV R0, 8(R19) +- // ADDV $8, R19 +- // BNE Rarg1, R19, -2(PC) ++ // MOVx R0, (R19) ++ // ADDV $sz, R19 ++ // BGEU Rarg1, R19, -2(PC) + { + name: "LoweredZero", + aux: "Int64", +@@ -331,32 +330,31 @@ func init() { + inputs: []regMask{buildReg("R19"), gp}, + clobbers: buildReg("R19"), + }, +- clobberFlags: true, ++ typ: "Mem", + faultOnNilArg0: true, + }, + + // large or unaligned move +- // arg0 = address of dst memory (in R4, changed as side effect) ++ // arg0 = address of dst memory (in R20, changed as side effect) + // arg1 = address of src memory (in R19, changed as side effect) + // arg2 = address of the last element of src + // arg3 = mem + // auxint = alignment + // returns mem +- // SUBV $8, R19 +- // MOVV 8(R19), Rtmp +- // MOVV Rtmp, (R4) +- // ADDV $8, R19 +- // ADDV $8, R4 +- // BNE Rarg2, R19, -4(PC) ++ // MOVx (R19), Rtmp ++ // MOVx Rtmp, (R20) ++ // ADDV $sz, R19 ++ // ADDV $sz, R20 ++ // BGEU Rarg2, R19, -4(PC) + { + name: "LoweredMove", + aux: "Int64", + argLength: 4, + reg: regInfo{ +- inputs: []regMask{buildReg("R4"), buildReg("R19"), gp}, +- clobbers: buildReg("R19 R4"), ++ inputs: []regMask{buildReg("R20"), buildReg("R19"), gp}, ++ clobbers: buildReg("R19 R20"), + }, +- clobberFlags: true, ++ typ: "Mem", + faultOnNilArg0: true, + faultOnNilArg1: true, + }, +diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go +index e95cb250d9..2b712a1189 100644 +--- a/src/cmd/compile/internal/ssa/opGen.go ++++ b/src/cmd/compile/internal/ssa/opGen.go +@@ -24289,7 +24289,6 @@ var opcodeTable = [...]opInfo{ + name: "LoweredZero", + auxType: auxInt64, + argLen: 3, +- clobberFlags: true, + faultOnNilArg0: true, + reg: regInfo{ + inputs: []inputInfo{ +@@ -24303,16 +24302,15 @@ var opcodeTable = [...]opInfo{ + name: "LoweredMove", + auxType: auxInt64, + argLen: 4, +- clobberFlags: true, + faultOnNilArg0: true, + faultOnNilArg1: true, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 8}, // R4 ++ {0, 524288}, // R20 + {1, 262144}, // R19 + {2, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + }, +- clobbers: 262152, // R4 R19 ++ clobbers: 786432, // R19 R20 + }, + }, + { +-- +2.20.1 + diff --git a/loongarch64/0009-cmd-internal-obj-loong64-add-atomic-memory-access-in.patch b/loongarch64/0009-cmd-internal-obj-loong64-add-atomic-memory-access-in.patch new file mode 100644 index 0000000000000000000000000000000000000000..501bff96067a66c180e743ea1aa6e36aa8489d1f --- /dev/null +++ b/loongarch64/0009-cmd-internal-obj-loong64-add-atomic-memory-access-in.patch @@ -0,0 +1,319 @@ +From d81d9f0dc5db63e9d9d4acceeaf1b484a8eea78e Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Sat, 1 Apr 2023 03:43:20 +0800 +Subject: [PATCH 09/51] cmd/internal/obj/loong64: add atomic memory access + instructions support +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The AM* atomic access instruction performs a sequence of “read-modify-write” +operations on a memory cell atomically. Specifically, it retrieves the old +value at the specified address in memory and writes it to the general register +rd, performs some simple operations on the old value in memory and the value +in the general register rk, and then write the result of the operation back +to the memory address pointed to by general register rj. + +Go asm syntax: + AM{SWAP/ADD/AND/OR/XOR/MAX/MIN}[DB]{W/V} RK, (RJ), RD + AM{MAX/MIN}[DB]{WU/VU} RK, (RJ), RD + +Equivalent platform assembler syntax: + am{swap/add/and/or/xor/max/min}[_db].{w/d} rd, rk, rj + am{max/min}[_db].{wu/du} rd, rk, rj + +Ref: https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html +Change-Id: I1707c484c3b2a0cf523255c80f566480a77432fb +--- + src/cmd/asm/internal/arch/loong64.go | 4 ++ + src/cmd/asm/internal/asm/asm.go | 14 +++- + .../asm/internal/asm/testdata/loong64enc1.s | 38 +++++++++++ + src/cmd/internal/obj/loong64/a.out.go | 38 +++++++++++ + src/cmd/internal/obj/loong64/anames.go | 36 ++++++++++ + src/cmd/internal/obj/loong64/asm.go | 67 +++++++++++++++++++ + 6 files changed, 194 insertions(+), 3 deletions(-) + +diff --git a/src/cmd/asm/internal/arch/loong64.go b/src/cmd/asm/internal/arch/loong64.go +index 2958ee1a86..bf34a94f07 100644 +--- a/src/cmd/asm/internal/arch/loong64.go ++++ b/src/cmd/asm/internal/arch/loong64.go +@@ -55,6 +55,10 @@ func IsLoong64RDTIME(op obj.As) bool { + return false + } + ++func IsLoong64AMO(op obj.As) bool { ++ return loong64.IsAtomicInst(op) ++} ++ + func loong64RegisterNumber(name string, n int16) (int16, bool) { + switch name { + case "F": +diff --git a/src/cmd/asm/internal/asm/asm.go b/src/cmd/asm/internal/asm/asm.go +index 563e794706..c8fff8e574 100644 +--- a/src/cmd/asm/internal/asm/asm.go ++++ b/src/cmd/asm/internal/asm/asm.go +@@ -664,9 +664,17 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) { + prog.Reg = p.getRegister(prog, op, &a[1]) + prog.To = a[2] + case sys.Loong64: +- prog.From = a[0] +- prog.Reg = p.getRegister(prog, op, &a[1]) +- prog.To = a[2] ++ switch { ++ // Loong64 atomic instructions with one input and two outputs. ++ case arch.IsLoong64AMO(op): ++ prog.From = a[0] ++ prog.To = a[1] ++ prog.RegTo2 = a[2].Reg ++ default: ++ prog.From = a[0] ++ prog.Reg = p.getRegister(prog, op, &a[1]) ++ prog.To = a[2] ++ } + case sys.ARM: + // Special cases. + if arch.IsARMSTREX(op) { +diff --git a/src/cmd/asm/internal/asm/testdata/loong64enc1.s b/src/cmd/asm/internal/asm/testdata/loong64enc1.s +index ea6c569f9d..288408b010 100644 +--- a/src/cmd/asm/internal/asm/testdata/loong64enc1.s ++++ b/src/cmd/asm/internal/asm/testdata/loong64enc1.s +@@ -233,3 +233,41 @@ lable2: + + MOVV FCC0, R4 // 04dc1401 + MOVV R4, FCC0 // 80d81401 ++ ++ // Loong64 atomic memory access instructions ++ AMSWAPW R14, (R13), R12 // ac396038 ++ AMSWAPV R14, (R13), R12 // acb96038 ++ AMADDW R14, (R13), R12 // ac396138 ++ AMADDV R14, (R13), R12 // acb96138 ++ AMANDW R14, (R13), R12 // ac396238 ++ AMANDV R14, (R13), R12 // acb96238 ++ AMORW R14, (R13), R12 // ac396338 ++ AMORV R14, (R13), R12 // acb96338 ++ AMXORW R14, (R13), R12 // ac396438 ++ AMXORV R14, (R13), R12 // acb96438 ++ AMMAXW R14, (R13), R12 // ac396538 ++ AMMAXV R14, (R13), R12 // acb96538 ++ AMMINW R14, (R13), R12 // ac396638 ++ AMMINV R14, (R13), R12 // acb96638 ++ AMMAXWU R14, (R13), R12 // ac396738 ++ AMMAXVU R14, (R13), R12 // acb96738 ++ AMMINWU R14, (R13), R12 // ac396838 ++ AMMINVU R14, (R13), R12 // acb96838 ++ AMSWAPDBW R14, (R13), R12 // ac396938 ++ AMSWAPDBV R14, (R13), R12 // acb96938 ++ AMADDDBW R14, (R13), R12 // ac396a38 ++ AMADDDBV R14, (R13), R12 // acb96a38 ++ AMANDDBW R14, (R13), R12 // ac396b38 ++ AMANDDBV R14, (R13), R12 // acb96b38 ++ AMORDBW R14, (R13), R12 // ac396c38 ++ AMORDBV R14, (R13), R12 // acb96c38 ++ AMXORDBW R14, (R13), R12 // ac396d38 ++ AMXORDBV R14, (R13), R12 // acb96d38 ++ AMMAXDBW R14, (R13), R12 // ac396e38 ++ AMMAXDBV R14, (R13), R12 // acb96e38 ++ AMMINDBW R14, (R13), R12 // ac396f38 ++ AMMINDBV R14, (R13), R12 // acb96f38 ++ AMMAXDBWU R14, (R13), R12 // ac397038 ++ AMMAXDBVU R14, (R13), R12 // acb97038 ++ AMMINDBWU R14, (R13), R12 // ac397138 ++ AMMINDBVU R14, (R13), R12 // acb97138 +diff --git a/src/cmd/internal/obj/loong64/a.out.go b/src/cmd/internal/obj/loong64/a.out.go +index 9527e99b56..3ed15fc7e7 100644 +--- a/src/cmd/internal/obj/loong64/a.out.go ++++ b/src/cmd/internal/obj/loong64/a.out.go +@@ -394,6 +394,44 @@ const ( + AMOVVF + AMOVVD + ++ // 2.2.7. Atomic Memory Access Instructions ++ AAMSWAPW ++ AAMSWAPV ++ AAMADDW ++ AAMADDV ++ AAMANDW ++ AAMANDV ++ AAMORW ++ AAMORV ++ AAMXORW ++ AAMXORV ++ AAMMAXW ++ AAMMAXV ++ AAMMINW ++ AAMMINV ++ AAMMAXWU ++ AAMMAXVU ++ AAMMINWU ++ AAMMINVU ++ AAMSWAPDBW ++ AAMSWAPDBV ++ AAMADDDBW ++ AAMADDDBV ++ AAMANDDBW ++ AAMANDDBV ++ AAMORDBW ++ AAMORDBV ++ AAMXORDBW ++ AAMXORDBV ++ AAMMAXDBW ++ AAMMAXDBV ++ AAMMINDBW ++ AAMMINDBV ++ AAMMAXDBWU ++ AAMMAXDBVU ++ AAMMINDBWU ++ AAMMINDBVU ++ + // 2.2.10. Other Miscellaneous Instructions + ARDTIMELW + ARDTIMEHW +diff --git a/src/cmd/internal/obj/loong64/anames.go b/src/cmd/internal/obj/loong64/anames.go +index f61756e7a8..d48ff8a281 100644 +--- a/src/cmd/internal/obj/loong64/anames.go ++++ b/src/cmd/internal/obj/loong64/anames.go +@@ -131,6 +131,42 @@ var Anames = []string{ + "MOVDV", + "MOVVF", + "MOVVD", ++ "AMSWAPW", ++ "AMSWAPV", ++ "AMADDW", ++ "AMADDV", ++ "AMANDW", ++ "AMANDV", ++ "AMORW", ++ "AMORV", ++ "AMXORW", ++ "AMXORV", ++ "AMMAXW", ++ "AMMAXV", ++ "AMMINW", ++ "AMMINV", ++ "AMMAXWU", ++ "AMMAXVU", ++ "AMMINWU", ++ "AMMINVU", ++ "AMSWAPDBW", ++ "AMSWAPDBV", ++ "AMADDDBW", ++ "AMADDDBV", ++ "AMANDDBW", ++ "AMANDDBV", ++ "AMORDBW", ++ "AMORDBV", ++ "AMXORDBW", ++ "AMXORDBV", ++ "AMMAXDBW", ++ "AMMAXDBV", ++ "AMMINDBW", ++ "AMMINDBV", ++ "AMMAXDBWU", ++ "AMMAXDBVU", ++ "AMMINDBWU", ++ "AMMINDBVU", + "RDTIMELW", + "RDTIMEHW", + "RDTIMED", +diff --git a/src/cmd/internal/obj/loong64/asm.go b/src/cmd/internal/obj/loong64/asm.go +index c8d00413a0..638bd1139f 100644 +--- a/src/cmd/internal/obj/loong64/asm.go ++++ b/src/cmd/internal/obj/loong64/asm.go +@@ -363,6 +363,8 @@ var optab = []Optab{ + {ARDTIMEHW, C_NONE, C_NONE, C_NONE, C_REG, C_REG, 62, 4, 0, 0}, + {ARDTIMED, C_NONE, C_NONE, C_NONE, C_REG, C_REG, 62, 4, 0, 0}, + ++ {AAMSWAPW, C_REG, C_NONE, C_NONE, C_ZOREG, C_REG, 66, 4, 0, 0}, ++ + {obj.AUNDEF, C_NONE, C_NONE, C_NONE, C_NONE, C_NONE, 49, 4, 0, 0}, + {obj.APCALIGN, C_SCON, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0}, + {obj.APCDATA, C_LCON, C_NONE, C_NONE, C_LCON, C_NONE, 0, 0, 0, 0}, +@@ -379,6 +381,51 @@ var optab = []Optab{ + {obj.AXXX, C_NONE, C_NONE, C_NONE, C_NONE, C_NONE, 0, 4, 0, 0}, + } + ++var atomicInst = map[obj.As]uint32{ ++ AAMSWAPW: 0x070C0 << 15, // amswap.w ++ AAMSWAPV: 0x070C1 << 15, // amswap.d ++ AAMADDW: 0x070C2 << 15, // amadd.w ++ AAMADDV: 0x070C3 << 15, // amadd.d ++ AAMANDW: 0x070C4 << 15, // amand.w ++ AAMANDV: 0x070C5 << 15, // amand.d ++ AAMORW: 0x070C6 << 15, // amor.w ++ AAMORV: 0x070C7 << 15, // amor.d ++ AAMXORW: 0x070C8 << 15, // amxor.w ++ AAMXORV: 0x070C9 << 15, // amxor.d ++ AAMMAXW: 0x070CA << 15, // ammax.w ++ AAMMAXV: 0x070CB << 15, // ammax.d ++ AAMMINW: 0x070CC << 15, // ammin.w ++ AAMMINV: 0x070CD << 15, // ammin.d ++ AAMMAXWU: 0x070CE << 15, // ammax.wu ++ AAMMAXVU: 0x070CF << 15, // ammax.du ++ AAMMINWU: 0x070D0 << 15, // ammin.wu ++ AAMMINVU: 0x070D1 << 15, // ammin.du ++ AAMSWAPDBW: 0x070D2 << 15, // amswap_db.w ++ AAMSWAPDBV: 0x070D3 << 15, // amswap_db.d ++ AAMADDDBW: 0x070D4 << 15, // amadd_db.w ++ AAMADDDBV: 0x070D5 << 15, // amadd_db.d ++ AAMANDDBW: 0x070D6 << 15, // amand_db.w ++ AAMANDDBV: 0x070D7 << 15, // amand_db.d ++ AAMORDBW: 0x070D8 << 15, // amor_db.w ++ AAMORDBV: 0x070D9 << 15, // amor_db.d ++ AAMXORDBW: 0x070DA << 15, // amxor_db.w ++ AAMXORDBV: 0x070DB << 15, // amxor_db.d ++ AAMMAXDBW: 0x070DC << 15, // ammax_db.w ++ AAMMAXDBV: 0x070DD << 15, // ammax_db.d ++ AAMMINDBW: 0x070DE << 15, // ammin_db.w ++ AAMMINDBV: 0x070DF << 15, // ammin_db.d ++ AAMMAXDBWU: 0x070E0 << 15, // ammax_db.wu ++ AAMMAXDBVU: 0x070E1 << 15, // ammax_db.du ++ AAMMINDBWU: 0x070E2 << 15, // ammin_db.wu ++ AAMMINDBVU: 0x070E3 << 15, // ammin_db.du ++} ++ ++func IsAtomicInst(as obj.As) bool { ++ _, ok := atomicInst[as] ++ ++ return ok ++} ++ + // pcAlignPadLength returns the number of bytes required to align pc to alignedValue, + // reporting an error if alignedValue is not a power of two or is out of range. + func pcAlignPadLength(ctxt *obj.Link, pc int64, alignedValue int64) int { +@@ -1172,6 +1219,14 @@ func buildop(ctxt *obj.Link) { + + case AMASKEQZ: + opset(AMASKNEZ, r0) ++ ++ case AAMSWAPW: ++ for i := range atomicInst { ++ if i == AAMSWAPW { ++ continue ++ } ++ opset(i, r0) ++ } + } + } + } +@@ -1797,6 +1852,18 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) { + rel2.Sym = p.From.Sym + rel2.Type = objabi.R_LOONG64_GOT_LO + rel2.Add = 0x0 ++ ++ case 66: // am* From, To, RegTo2 ==> am* RegTo2, From, To ++ rk := p.From.Reg ++ rj := p.To.Reg ++ rd := p.RegTo2 ++ ++ // See section 2.2.7.1 of https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html ++ // for the register usage constraints. ++ if rd == rj || rd == rk { ++ c.ctxt.Diag("illegal register combination: %v\n", p) ++ } ++ o1 = OP_RRR(atomicInst[p.As], uint32(rk), uint32(rj), uint32(rd)) + } + + out[0] = o1 +-- +2.20.1 + diff --git a/loongarch64/0010-cmd-compiler-runtime-internal-atomic-optimize-xchg-a.patch b/loongarch64/0010-cmd-compiler-runtime-internal-atomic-optimize-xchg-a.patch new file mode 100644 index 0000000000000000000000000000000000000000..dac73092e3a5d17fb66513c099b92896e4cc806a --- /dev/null +++ b/loongarch64/0010-cmd-compiler-runtime-internal-atomic-optimize-xchg-a.patch @@ -0,0 +1,164 @@ +From 462806ee9f1d8e3ea9ceb6b8f2ec6a311d038298 Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Sat, 1 Apr 2023 08:49:58 +0800 +Subject: [PATCH 10/51] cmd/compiler,runtime/internal/atomic: optimize xchg and + xchg64 on loong64 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Use Loong64's atomic operation instruction AMSWAPx to implement Xchg and Xchg64 + +goos: linux +goarch: loong64 +pkg: runtime/internal/atomic + │ bench.old │ bench.new │ + │ sec/op │ sec/op vs base │ +Xchg 30.06n ± 0% 13.66n ± 0% -54.56% (p=0.000 n=20) +Xchg-2 37.43n ± 6% 23.55n ± 1% -37.06% (p=0.000 n=20) +Xchg-4 37.16n ± 5% 33.25n ± 2% -10.55% (p=0.000 n=20) +Xchg-8 37.81n ± 3% 32.12n ± 1% -15.04% (p=0.000 n=20) +Xchg-16 37.55n ± 0% 33.70n ± 0% -10.25% (p=0.000 n=20) +Xchg64 30.05n ± 0% 14.13n ± 0% -52.96% (p=0.000 n=20) +Xchg64-2 37.42n ± 1% 21.80n ± 0% -41.74% (p=0.000 n=20) +Xchg64-4 38.17n ± 6% 31.95n ± 1% -16.30% (p=0.000 n=20) +Xchg64-8 37.44n ± 1% 32.12n ± 2% -14.18% (p=0.000 n=20) +Xchg64-16 37.56n ± 0% 33.65n ± 0% -10.41% (p=0.000 n=20) +geomean 36.54n 25.65n -28.61% + +Updates #59120. + +Change-Id: I1f78f547b818ea6ead9480254c05745e2eee4d68 +--- + src/cmd/compile/internal/loong64/ssa.go | 38 ++++--------------- + .../compile/internal/ssa/_gen/LOONG64Ops.go | 6 --- + src/runtime/internal/atomic/atomic_loong64.s | 30 +++++++-------- + 3 files changed, 22 insertions(+), 52 deletions(-) + +diff --git a/src/cmd/compile/internal/loong64/ssa.go b/src/cmd/compile/internal/loong64/ssa.go +index f74f90fb5f..e103c896e6 100644 +--- a/src/cmd/compile/internal/loong64/ssa.go ++++ b/src/cmd/compile/internal/loong64/ssa.go +@@ -495,40 +495,18 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) { + p.To.Reg = v.Args[0].Reg() + s.Prog(loong64.ADBAR) + case ssa.OpLOONG64LoweredAtomicExchange32, ssa.OpLOONG64LoweredAtomicExchange64: +- // DBAR +- // MOVV Rarg1, Rtmp +- // LL (Rarg0), Rout +- // SC Rtmp, (Rarg0) +- // BEQ Rtmp, -3(PC) +- // DBAR +- ll := loong64.ALLV +- sc := loong64.ASCV ++ // AMSWAPx Rarg1, (Rarg0), Rout ++ amswapx := loong64.AAMSWAPV + if v.Op == ssa.OpLOONG64LoweredAtomicExchange32 { +- ll = loong64.ALL +- sc = loong64.ASC ++ amswapx = loong64.AAMSWAPW + } +- s.Prog(loong64.ADBAR) +- p := s.Prog(loong64.AMOVV) ++ p := s.Prog(amswapx) + p.From.Type = obj.TYPE_REG + p.From.Reg = v.Args[1].Reg() +- p.To.Type = obj.TYPE_REG +- p.To.Reg = loong64.REGTMP +- p1 := s.Prog(ll) +- p1.From.Type = obj.TYPE_MEM +- p1.From.Reg = v.Args[0].Reg() +- p1.To.Type = obj.TYPE_REG +- p1.To.Reg = v.Reg0() +- p2 := s.Prog(sc) +- p2.From.Type = obj.TYPE_REG +- p2.From.Reg = loong64.REGTMP +- p2.To.Type = obj.TYPE_MEM +- p2.To.Reg = v.Args[0].Reg() +- p3 := s.Prog(loong64.ABEQ) +- p3.From.Type = obj.TYPE_REG +- p3.From.Reg = loong64.REGTMP +- p3.To.Type = obj.TYPE_BRANCH +- p3.To.SetTarget(p) +- s.Prog(loong64.ADBAR) ++ p.To.Type = obj.TYPE_MEM ++ p.To.Reg = v.Args[0].Reg() ++ p.RegTo2 = v.Reg0() ++ + case ssa.OpLOONG64LoweredAtomicAdd32, ssa.OpLOONG64LoweredAtomicAdd64: + // DBAR + // LL (Rarg0), Rout +diff --git a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go +index cb058f45c0..09c3df6af2 100644 +--- a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go ++++ b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go +@@ -377,12 +377,6 @@ func init() { + + // atomic exchange. + // store arg1 to arg0. arg2=mem. returns . +- // DBAR +- // LL (Rarg0), Rout +- // MOVV Rarg1, Rtmp +- // SC Rtmp, (Rarg0) +- // BEQ Rtmp, -3(PC) +- // DBAR + {name: "LoweredAtomicExchange32", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true}, + {name: "LoweredAtomicExchange64", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true}, + +diff --git a/src/runtime/internal/atomic/atomic_loong64.s b/src/runtime/internal/atomic/atomic_loong64.s +index 34193add3e..ec34d254fc 100644 +--- a/src/runtime/internal/atomic/atomic_loong64.s ++++ b/src/runtime/internal/atomic/atomic_loong64.s +@@ -121,35 +121,33 @@ TEXT ·Xadd64(SB), NOSPLIT, $0-24 + DBAR + RET + ++// func Xchg(ptr *uint32, new uint32) uint32 + TEXT ·Xchg(SB), NOSPLIT, $0-20 + MOVV ptr+0(FP), R4 + MOVW new+8(FP), R5 +- +- DBAR +- MOVV R5, R6 +- LL (R4), R7 +- SC R6, (R4) +- BEQ R6, -3(PC) +- MOVW R7, ret+16(FP) +- DBAR ++ AMSWAPW R5, (R4), R6 ++ MOVW R6, ret+16(FP) + RET + ++// func Xchg64(ptr *uint64, new uint64) uint64 + TEXT ·Xchg64(SB), NOSPLIT, $0-24 + MOVV ptr+0(FP), R4 + MOVV new+8(FP), R5 +- +- DBAR +- MOVV R5, R6 +- LLV (R4), R7 +- SCV R6, (R4) +- BEQ R6, -3(PC) +- MOVV R7, ret+16(FP) +- DBAR ++ AMSWAPV R5, (R4), R6 ++ MOVV R6, ret+16(FP) + RET + + TEXT ·Xchguintptr(SB), NOSPLIT, $0-24 + JMP ·Xchg64(SB) + ++// func Xchgint32(ptr *int32, new int32) int32 ++TEXT ·Xchgint32(SB), NOSPLIT, $0-20 ++ JMP ·Xchg(SB) ++ ++// func Xchgint64(ptr *int64, new int64) int64 ++TEXT ·Xchgint64(SB), NOSPLIT, $0-24 ++ JMP ·Xchg64(SB) ++ + TEXT ·StorepNoWB(SB), NOSPLIT, $0-16 + JMP ·Store64(SB) + +-- +2.20.1 + diff --git a/loongarch64/0011-cmd-compiler-runtime-internal-atomic-optimize-xadd-a.patch b/loongarch64/0011-cmd-compiler-runtime-internal-atomic-optimize-xadd-a.patch new file mode 100644 index 0000000000000000000000000000000000000000..3989118e145c8c8efb2a98af77ef462b73bd1aab --- /dev/null +++ b/loongarch64/0011-cmd-compiler-runtime-internal-atomic-optimize-xadd-a.patch @@ -0,0 +1,182 @@ +From fc4462319d704098aaf0090223abe912db88c35a Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Mon, 3 Apr 2023 12:11:46 +0800 +Subject: [PATCH 11/51] cmd/compiler,runtime/internal/atomic: optimize xadd and + xadd64 on loong64 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Use Loong64's atomic operation instruction AMADDx to implement Xadd and Xadd64 + +goos: linux +goarch: loong64 +pkg: runtime/internal/atomic + │ bench.old │ bench.new │ + │ sec/op │ sec/op vs base │ +Xadd 27.24n ± 0% 27.23n ± 0% -0.04% (p=0.000 n=35) +Xadd-2 31.90n ± 0% 31.91n ± 0% ~ (p=0.765 n=35) +Xadd-4 31.90n ± 0% 31.90n ± 0% ~ (p=0.636 n=35) +Xadd-8 32.61n ± 3% 32.50n ± 4% ~ (p=0.883 n=35) +Xadd-16 32.36n ± 1% 32.33n ± 1% ~ (p=0.266 n=35) +Xadd64 27.24n ± 0% 27.23n ± 0% -0.04% (p=0.000 n=35) +Xadd64-2 31.92n ± 0% 31.92n ± 0% ~ (p=0.617 n=35) +Xadd64-4 31.90n ± 0% 31.90n ± 0% 0.00% (p=0.011 n=35) +Xadd64-8 32.95n ± 1% 32.89n ± 3% ~ (p=1.000 n=35) +Xadd64-16 32.16n ± 1% 32.31n ± 1% ~ (p=0.057 n=35) +geomean 31.15n 31.14n -0.02% + +Change-Id: I982539c2aa04680e9dd11b099ba8d5f215bf9b32 +--- + src/cmd/compile/internal/loong64/ssa.go | 51 ++++++------------- + .../compile/internal/ssa/_gen/LOONG64Ops.go | 7 --- + src/runtime/internal/atomic/atomic_loong64.s | 29 +++++------ + 3 files changed, 27 insertions(+), 60 deletions(-) + +diff --git a/src/cmd/compile/internal/loong64/ssa.go b/src/cmd/compile/internal/loong64/ssa.go +index e103c896e6..f809fbac5f 100644 +--- a/src/cmd/compile/internal/loong64/ssa.go ++++ b/src/cmd/compile/internal/loong64/ssa.go +@@ -508,48 +508,27 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) { + p.RegTo2 = v.Reg0() + + case ssa.OpLOONG64LoweredAtomicAdd32, ssa.OpLOONG64LoweredAtomicAdd64: +- // DBAR +- // LL (Rarg0), Rout +- // ADDV Rarg1, Rout, Rtmp +- // SC Rtmp, (Rarg0) +- // BEQ Rtmp, -3(PC) +- // DBAR +- // ADDV Rarg1, Rout +- ll := loong64.ALLV +- sc := loong64.ASCV ++ // AMADDx Rarg1, (Rarg0), Rout ++ // ADDxU Rarg1, Rout, Rout ++ amaddx := loong64.AAMADDV ++ addx := loong64.AADDVU + if v.Op == ssa.OpLOONG64LoweredAtomicAdd32 { +- ll = loong64.ALL +- sc = loong64.ASC ++ amaddx = loong64.AAMADDW ++ addx = loong64.AADDU + } +- s.Prog(loong64.ADBAR) +- p := s.Prog(ll) +- p.From.Type = obj.TYPE_MEM +- p.From.Reg = v.Args[0].Reg() +- p.To.Type = obj.TYPE_REG +- p.To.Reg = v.Reg0() +- p1 := s.Prog(loong64.AADDVU) ++ p := s.Prog(amaddx) ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = v.Args[1].Reg() ++ p.To.Type = obj.TYPE_MEM ++ p.To.Reg = v.Args[0].Reg() ++ p.RegTo2 = v.Reg0() ++ p1 := s.Prog(addx) + p1.From.Type = obj.TYPE_REG + p1.From.Reg = v.Args[1].Reg() + p1.Reg = v.Reg0() + p1.To.Type = obj.TYPE_REG +- p1.To.Reg = loong64.REGTMP +- p2 := s.Prog(sc) +- p2.From.Type = obj.TYPE_REG +- p2.From.Reg = loong64.REGTMP +- p2.To.Type = obj.TYPE_MEM +- p2.To.Reg = v.Args[0].Reg() +- p3 := s.Prog(loong64.ABEQ) +- p3.From.Type = obj.TYPE_REG +- p3.From.Reg = loong64.REGTMP +- p3.To.Type = obj.TYPE_BRANCH +- p3.To.SetTarget(p) +- s.Prog(loong64.ADBAR) +- p4 := s.Prog(loong64.AADDVU) +- p4.From.Type = obj.TYPE_REG +- p4.From.Reg = v.Args[1].Reg() +- p4.Reg = v.Reg0() +- p4.To.Type = obj.TYPE_REG +- p4.To.Reg = v.Reg0() ++ p1.To.Reg = v.Reg0() ++ + case ssa.OpLOONG64LoweredAtomicAddconst32, ssa.OpLOONG64LoweredAtomicAddconst64: + // DBAR + // LL (Rarg0), Rout +diff --git a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go +index 09c3df6af2..b83a7b0128 100644 +--- a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go ++++ b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go +@@ -382,13 +382,6 @@ func init() { + + // atomic add. + // *arg0 += arg1. arg2=mem. returns . +- // DBAR +- // LL (Rarg0), Rout +- // ADDV Rarg1, Rout, Rtmp +- // SC Rtmp, (Rarg0) +- // BEQ Rtmp, -3(PC) +- // DBAR +- // ADDV Rarg1, Rout + {name: "LoweredAtomicAdd32", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true}, + {name: "LoweredAtomicAdd64", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true}, + // *arg0 += auxint. arg1=mem. returns . auxint is 32-bit. +diff --git a/src/runtime/internal/atomic/atomic_loong64.s b/src/runtime/internal/atomic/atomic_loong64.s +index ec34d254fc..eadd031553 100644 +--- a/src/runtime/internal/atomic/atomic_loong64.s ++++ b/src/runtime/internal/atomic/atomic_loong64.s +@@ -78,6 +78,9 @@ TEXT ·Xadduintptr(SB), NOSPLIT, $0-24 + TEXT ·Loadint64(SB), NOSPLIT, $0-16 + JMP ·Load64(SB) + ++TEXT ·Xaddint32(SB),NOSPLIT,$0-20 ++ JMP ·Xadd(SB) ++ + TEXT ·Xaddint64(SB), NOSPLIT, $0-24 + JMP ·Xadd64(SB) + +@@ -91,34 +94,26 @@ TEXT ·Xaddint64(SB), NOSPLIT, $0-24 + TEXT ·Casp1(SB), NOSPLIT, $0-25 + JMP ·Cas64(SB) + +-// uint32 xadd(uint32 volatile *ptr, int32 delta) + // Atomically: + // *val += delta; + // return *val; ++// ++// func Xadd(ptr *uint32, delta int32) uint32 + TEXT ·Xadd(SB), NOSPLIT, $0-20 + MOVV ptr+0(FP), R4 + MOVW delta+8(FP), R5 +- DBAR +- LL (R4), R6 +- ADDU R6, R5, R7 +- MOVV R7, R6 +- SC R7, (R4) +- BEQ R7, -4(PC) +- MOVW R6, ret+16(FP) +- DBAR ++ AMADDW R5, (R4), R6 ++ ADDU R6, R5, R4 ++ MOVW R4, ret+16(FP) + RET + ++// func Xadd64(ptr *uint64, delta int64) uint64 + TEXT ·Xadd64(SB), NOSPLIT, $0-24 + MOVV ptr+0(FP), R4 + MOVV delta+8(FP), R5 +- DBAR +- LLV (R4), R6 +- ADDVU R6, R5, R7 +- MOVV R7, R6 +- SCV R7, (R4) +- BEQ R7, -4(PC) +- MOVV R6, ret+16(FP) +- DBAR ++ AMADDV R5, (R4), R6 ++ ADDVU R6, R5, R4 ++ MOVV R4, ret+16(FP) + RET + + // func Xchg(ptr *uint32, new uint32) uint32 +-- +2.20.1 + diff --git a/loongarch64/0012-cmd-compiler-runtime-internal-atomic-optimize-And-32.patch b/loongarch64/0012-cmd-compiler-runtime-internal-atomic-optimize-And-32.patch new file mode 100644 index 0000000000000000000000000000000000000000..fd6262859ae58f4b1abe66c2169ecd7e0ead3b83 --- /dev/null +++ b/loongarch64/0012-cmd-compiler-runtime-internal-atomic-optimize-And-32.patch @@ -0,0 +1,399 @@ +From b8c1d49cc670585a367cfe1e3ccfac0445591168 Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Wed, 5 Apr 2023 22:15:46 +0800 +Subject: [PATCH 12/51] cmd/compiler,runtime/internal/atomic: optimize + And{32,8} and Or{32,8} on loong64 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Use Loong64's atomic operation instruction AMANDW to implement And{32,8}, +AMORW to implement Or{32,8}, and intrinsify them. + +goos: linux +goarch: loong64 +pkg: runtime/internal/atomic + │ bench.old │ bench.new │ + │ sec/op │ sec/op vs base │ +And8 36.25n ± 0% 17.14n ± 0% -52.72% (p=0.000 n=25) +And8-2 36.19n ± 0% 17.16n ± 0% -52.58% (p=0.000 n=25) +And8-4 36.12n ± 0% 17.15n ± 0% -52.52% (p=0.000 n=25) +And8-8 36.15n ± 0% 17.15n ± 0% -52.56% (p=0.000 n=25) +And8-16 36.15n ± 0% 17.15n ± 0% -52.56% (p=0.000 n=25) +And 35.84n ± 0% 16.15n ± 0% -54.94% (p=0.000 n=25) +And-2 35.79n ± 0% 16.19n ± 0% -54.76% (p=0.000 n=25) +And-4 35.78n ± 0% 16.18n ± 0% -54.78% (p=0.000 n=25) +And-8 35.79n ± 0% 16.19n ± 0% -54.76% (p=0.000 n=25) +And-16 35.79n ± 0% 16.19n ± 0% -54.76% (p=0.000 n=25) +And8Parallel 35.43n ± 0% 17.31n ± 0% -51.14% (p=0.000 n=25) +And8Parallel-2 42.19n ± 3% 26.85n ± 2% -36.36% (p=0.000 n=25) +And8Parallel-4 46.59n ± 2% 33.31n ± 1% -28.50% (p=0.000 n=25) +And8Parallel-8 45.36n ± 1% 32.64n ± 2% -28.04% (p=0.000 n=25) +And8Parallel-16 45.24n ± 0% 33.63n ± 0% -25.66% (p=0.000 n=25) +AndParallel 34.20n ± 0% 16.39n ± 0% -52.08% (p=0.000 n=25) +AndParallel-2 42.30n ± 3% 24.54n ± 4% -41.99% (p=0.000 n=25) +AndParallel-4 44.58n ± 2% 33.64n ± 7% -24.54% (p=0.000 n=25) +AndParallel-8 45.27n ± 1% 34.14n ± 1% -24.59% (p=0.000 n=25) +AndParallel-16 44.77n ± 1% 33.68n ± 0% -24.77% (p=0.000 n=25) +Or8 35.84n ± 0% 16.67n ± 0% -53.49% (p=0.000 n=25) +Or8-2 35.78n ± 0% 16.67n ± 0% -53.41% (p=0.000 n=25) +Or8-4 35.82n ± 0% 16.69n ± 0% -53.41% (p=0.000 n=25) +Or8-8 35.84n ± 0% 16.68n ± 0% -53.46% (p=0.000 n=25) +Or8-16 35.76n ± 0% 16.68n ± 0% -53.36% (p=0.000 n=25) +Or 35.71n ± 0% 16.17n ± 0% -54.72% (p=0.000 n=25) +Or-2 35.78n ± 0% 16.19n ± 0% -54.75% (p=0.000 n=25) +Or-4 35.81n ± 0% 16.19n ± 0% -54.79% (p=0.000 n=25) +Or-8 35.81n ± 0% 16.19n ± 0% -54.79% (p=0.000 n=25) +Or-16 35.81n ± 0% 16.19n ± 0% -54.79% (p=0.000 n=25) +Or8Parallel 34.56n ± 0% 16.89n ± 0% -51.13% (p=0.000 n=25) +Or8Parallel-2 43.00n ± 0% 33.59n ± 19% -21.88% (p=0.000 n=25) +Or8Parallel-4 45.62n ± 0% 30.48n ± 0% -33.19% (p=0.000 n=25) +Or8Parallel-8 44.58n ± 1% 33.16n ± 2% -25.62% (p=0.000 n=25) +Or8Parallel-16 44.80n ± 0% 33.67n ± 0% -24.84% (p=0.000 n=25) +OrParallel 34.16n ± 0% 16.39n ± 0% -52.02% (p=0.000 n=25) +OrParallel-2 42.44n ± 0% 25.44n ± 1% -40.06% (p=0.000 n=25) +OrParallel-4 45.91n ± 2% 32.47n ± 4% -29.27% (p=0.000 n=25) +OrParallel-8 45.37n ± 2% 33.08n ± 2% -27.09% (p=0.000 n=25) +OrParallel-16 44.60n ± 1% 33.67n ± 0% -24.51% (p=0.000 n=25) +geomean 38.98n 21.45n -44.96% + +Updates #59120. + +Change-Id: Ib998a26613adaa5ed2c23ed528245a4e83d10eca +--- + src/cmd/compile/internal/loong64/ssa.go | 8 ++ + .../compile/internal/ssa/_gen/LOONG64.rules | 19 +++++ + .../compile/internal/ssa/_gen/LOONG64Ops.go | 5 ++ + src/cmd/compile/internal/ssa/opGen.go | 34 ++++++++ + .../compile/internal/ssa/rewriteLOONG64.go | 81 +++++++++++++++++++ + src/cmd/compile/internal/ssagen/ssa.go | 8 +- + src/runtime/internal/atomic/atomic_loong64.s | 30 +------ + 7 files changed, 155 insertions(+), 30 deletions(-) + +diff --git a/src/cmd/compile/internal/loong64/ssa.go b/src/cmd/compile/internal/loong64/ssa.go +index f809fbac5f..8d305c4f57 100644 +--- a/src/cmd/compile/internal/loong64/ssa.go ++++ b/src/cmd/compile/internal/loong64/ssa.go +@@ -507,6 +507,14 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) { + p.To.Reg = v.Args[0].Reg() + p.RegTo2 = v.Reg0() + ++ case ssa.OpLOONG64LoweredAtomicAnd32, ssa.OpLOONG64LoweredAtomicOr32: ++ p := s.Prog(v.Op.Asm()) ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = v.Args[1].Reg() ++ p.To.Type = obj.TYPE_MEM ++ p.To.Reg = v.Args[0].Reg() ++ p.RegTo2 = loong64.REGZERO ++ + case ssa.OpLOONG64LoweredAtomicAdd32, ssa.OpLOONG64LoweredAtomicAdd64: + // AMADDx Rarg1, (Rarg0), Rout + // ADDxU Rarg1, Rout, Rout +diff --git a/src/cmd/compile/internal/ssa/_gen/LOONG64.rules b/src/cmd/compile/internal/ssa/_gen/LOONG64.rules +index b9aaa3ff7f..25caad4406 100644 +--- a/src/cmd/compile/internal/ssa/_gen/LOONG64.rules ++++ b/src/cmd/compile/internal/ssa/_gen/LOONG64.rules +@@ -405,6 +405,25 @@ + (AtomicCompareAndSwap32 ptr old new mem) => (LoweredAtomicCas32 ptr (SignExt32to64 old) new mem) + (AtomicCompareAndSwap64 ...) => (LoweredAtomicCas64 ...) + ++// AtomicAnd8(ptr,val) => LoweredAtomicAnd32(ptr&^3, ^((uint8(val) ^ 0xff) << ((ptr & 3) * 8))) ++(AtomicAnd8 ptr val mem) => ++ (LoweredAtomicAnd32 (AND (MOVVconst [^3]) ptr) ++ (OR (SLLV (ZeroExt8to32 val) ++ (SLLVconst [3] ++ (ANDconst [3] ptr))) ++ (NORconst [0] (SLLV ++ (MOVVconst [0xff]) (SLLVconst [3] ++ (ANDconst [3] ptr))))) mem) ++(AtomicAnd32 ...) => (LoweredAtomicAnd32 ...) ++ ++// AtomicOr8(ptr,val) => LoweredAtomicOr32(ptr&^3, uint32(val) << ((ptr & 3) * 8)) ++(AtomicOr8 ptr val mem) => ++ (LoweredAtomicOr32 (AND (MOVVconst [^3]) ptr) ++ (SLLV (ZeroExt8to32 val) ++ (SLLVconst [3] ++ (ANDconst [3] ptr))) mem) ++(AtomicOr32 ...) => (LoweredAtomicOr32 ...) ++ + // checks + (NilCheck ...) => (LoweredNilCheck ...) + (IsNonNil ptr) => (SGTU ptr (MOVVconst [0])) +diff --git a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go +index b83a7b0128..41cc431e8b 100644 +--- a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go ++++ b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go +@@ -380,6 +380,11 @@ func init() { + {name: "LoweredAtomicExchange32", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true}, + {name: "LoweredAtomicExchange64", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true}, + ++ // Atomic 32 bit AND/OR. ++ // *arg0 &= (|=) arg1. arg2=mem. returns nil. ++ {name: "LoweredAtomicAnd32", argLength: 3, reg: gpxchg, asm: "AMANDW", faultOnNilArg0: true, hasSideEffects: true}, ++ {name: "LoweredAtomicOr32", argLength: 3, reg: gpxchg, asm: "AMORW", faultOnNilArg0: true, hasSideEffects: true}, ++ + // atomic add. + // *arg0 += arg1. arg2=mem. returns . + {name: "LoweredAtomicAdd32", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true}, +diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go +index 2b712a1189..55a42ae782 100644 +--- a/src/cmd/compile/internal/ssa/opGen.go ++++ b/src/cmd/compile/internal/ssa/opGen.go +@@ -1827,6 +1827,8 @@ const ( + OpLOONG64LoweredAtomicStorezero64 + OpLOONG64LoweredAtomicExchange32 + OpLOONG64LoweredAtomicExchange64 ++ OpLOONG64LoweredAtomicAnd32 ++ OpLOONG64LoweredAtomicOr32 + OpLOONG64LoweredAtomicAdd32 + OpLOONG64LoweredAtomicAdd64 + OpLOONG64LoweredAtomicAddconst32 +@@ -24444,6 +24446,38 @@ var opcodeTable = [...]opInfo{ + }, + }, + }, ++ { ++ name: "LoweredAtomicAnd32", ++ argLen: 3, ++ faultOnNilArg0: true, ++ hasSideEffects: true, ++ asm: loong64.AAMANDW, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB ++ }, ++ outputs: []outputInfo{ ++ {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ }, ++ }, ++ }, ++ { ++ name: "LoweredAtomicOr32", ++ argLen: 3, ++ faultOnNilArg0: true, ++ hasSideEffects: true, ++ asm: loong64.AAMORW, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB ++ }, ++ outputs: []outputInfo{ ++ {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ }, ++ }, ++ }, + { + name: "LoweredAtomicAdd32", + argLen: 3, +diff --git a/src/cmd/compile/internal/ssa/rewriteLOONG64.go b/src/cmd/compile/internal/ssa/rewriteLOONG64.go +index 757524bdbb..bb09bd2e58 100644 +--- a/src/cmd/compile/internal/ssa/rewriteLOONG64.go ++++ b/src/cmd/compile/internal/ssa/rewriteLOONG64.go +@@ -50,6 +50,11 @@ func rewriteValueLOONG64(v *Value) bool { + case OpAtomicAdd64: + v.Op = OpLOONG64LoweredAtomicAdd64 + return true ++ case OpAtomicAnd32: ++ v.Op = OpLOONG64LoweredAtomicAnd32 ++ return true ++ case OpAtomicAnd8: ++ return rewriteValueLOONG64_OpAtomicAnd8(v) + case OpAtomicCompareAndSwap32: + return rewriteValueLOONG64_OpAtomicCompareAndSwap32(v) + case OpAtomicCompareAndSwap64: +@@ -73,6 +78,11 @@ func rewriteValueLOONG64(v *Value) bool { + case OpAtomicLoadPtr: + v.Op = OpLOONG64LoweredAtomicLoad64 + return true ++ case OpAtomicOr32: ++ v.Op = OpLOONG64LoweredAtomicOr32 ++ return true ++ case OpAtomicOr8: ++ return rewriteValueLOONG64_OpAtomicOr8(v) + case OpAtomicStore32: + v.Op = OpLOONG64LoweredAtomicStore32 + return true +@@ -718,6 +728,46 @@ func rewriteValueLOONG64_OpAddr(v *Value) bool { + return true + } + } ++func rewriteValueLOONG64_OpAtomicAnd8(v *Value) bool { ++ v_2 := v.Args[2] ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (AtomicAnd8 ptr val mem) ++ // result: (LoweredAtomicAnd32 (AND (MOVVconst [^3]) ptr) (OR (SLLV (ZeroExt8to32 val) (SLLVconst [3] (ANDconst [3] ptr))) (NORconst [0] (SLLV (MOVVconst [0xff]) (SLLVconst [3] (ANDconst [3] ptr))))) mem) ++ for { ++ ptr := v_0 ++ val := v_1 ++ mem := v_2 ++ v.reset(OpLOONG64LoweredAtomicAnd32) ++ v0 := b.NewValue0(v.Pos, OpLOONG64AND, typ.Uintptr) ++ v1 := b.NewValue0(v.Pos, OpLOONG64MOVVconst, typ.UInt64) ++ v1.AuxInt = int64ToAuxInt(^3) ++ v0.AddArg2(v1, ptr) ++ v2 := b.NewValue0(v.Pos, OpLOONG64OR, typ.UInt64) ++ v3 := b.NewValue0(v.Pos, OpLOONG64SLLV, typ.UInt32) ++ v4 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32) ++ v4.AddArg(val) ++ v5 := b.NewValue0(v.Pos, OpLOONG64SLLVconst, typ.UInt64) ++ v5.AuxInt = int64ToAuxInt(3) ++ v6 := b.NewValue0(v.Pos, OpLOONG64ANDconst, typ.UInt64) ++ v6.AuxInt = int64ToAuxInt(3) ++ v6.AddArg(ptr) ++ v5.AddArg(v6) ++ v3.AddArg2(v4, v5) ++ v7 := b.NewValue0(v.Pos, OpLOONG64NORconst, typ.UInt64) ++ v7.AuxInt = int64ToAuxInt(0) ++ v8 := b.NewValue0(v.Pos, OpLOONG64SLLV, typ.UInt64) ++ v9 := b.NewValue0(v.Pos, OpLOONG64MOVVconst, typ.UInt64) ++ v9.AuxInt = int64ToAuxInt(0xff) ++ v8.AddArg2(v9, v5) ++ v7.AddArg(v8) ++ v2.AddArg2(v3, v7) ++ v.AddArg3(v0, v2, mem) ++ return true ++ } ++} + func rewriteValueLOONG64_OpAtomicCompareAndSwap32(v *Value) bool { + v_3 := v.Args[3] + v_2 := v.Args[2] +@@ -739,6 +789,37 @@ func rewriteValueLOONG64_OpAtomicCompareAndSwap32(v *Value) bool { + return true + } + } ++func rewriteValueLOONG64_OpAtomicOr8(v *Value) bool { ++ v_2 := v.Args[2] ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (AtomicOr8 ptr val mem) ++ // result: (LoweredAtomicOr32 (AND (MOVVconst [^3]) ptr) (SLLV (ZeroExt8to32 val) (SLLVconst [3] (ANDconst [3] ptr))) mem) ++ for { ++ ptr := v_0 ++ val := v_1 ++ mem := v_2 ++ v.reset(OpLOONG64LoweredAtomicOr32) ++ v0 := b.NewValue0(v.Pos, OpLOONG64AND, typ.Uintptr) ++ v1 := b.NewValue0(v.Pos, OpLOONG64MOVVconst, typ.UInt64) ++ v1.AuxInt = int64ToAuxInt(^3) ++ v0.AddArg2(v1, ptr) ++ v2 := b.NewValue0(v.Pos, OpLOONG64SLLV, typ.UInt32) ++ v3 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32) ++ v3.AddArg(val) ++ v4 := b.NewValue0(v.Pos, OpLOONG64SLLVconst, typ.UInt64) ++ v4.AuxInt = int64ToAuxInt(3) ++ v5 := b.NewValue0(v.Pos, OpLOONG64ANDconst, typ.UInt64) ++ v5.AuxInt = int64ToAuxInt(3) ++ v5.AddArg(ptr) ++ v4.AddArg(v5) ++ v2.AddArg2(v3, v4) ++ v.AddArg3(v0, v2, mem) ++ return true ++ } ++} + func rewriteValueLOONG64_OpAvg64u(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] +diff --git a/src/cmd/compile/internal/ssagen/ssa.go b/src/cmd/compile/internal/ssagen/ssa.go +index e994577c64..02a69cc44a 100644 +--- a/src/cmd/compile/internal/ssagen/ssa.go ++++ b/src/cmd/compile/internal/ssagen/ssa.go +@@ -4352,25 +4352,25 @@ func InitTables() { + s.vars[memVar] = s.newValue3(ssa.OpAtomicAnd8, types.TypeMem, args[0], args[1], s.mem()) + return nil + }, +- sys.AMD64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X) ++ sys.AMD64, sys.Loong64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X) + addF("runtime/internal/atomic", "And", + func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { + s.vars[memVar] = s.newValue3(ssa.OpAtomicAnd32, types.TypeMem, args[0], args[1], s.mem()) + return nil + }, +- sys.AMD64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X) ++ sys.AMD64, sys.Loong64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X) + addF("runtime/internal/atomic", "Or8", + func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { + s.vars[memVar] = s.newValue3(ssa.OpAtomicOr8, types.TypeMem, args[0], args[1], s.mem()) + return nil + }, +- sys.AMD64, sys.ARM64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X) ++ sys.AMD64, sys.ARM64, sys.Loong64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X) + addF("runtime/internal/atomic", "Or", + func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { + s.vars[memVar] = s.newValue3(ssa.OpAtomicOr32, types.TypeMem, args[0], args[1], s.mem()) + return nil + }, +- sys.AMD64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X) ++ sys.AMD64, sys.Loong64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X) + + atomicAndOrEmitterARM64 := func(s *state, n *ir.CallExpr, args []*ssa.Value, op ssa.Op, typ types.Kind) { + s.vars[memVar] = s.newValue3(op, types.TypeMem, args[0], args[1], s.mem()) +diff --git a/src/runtime/internal/atomic/atomic_loong64.s b/src/runtime/internal/atomic/atomic_loong64.s +index eadd031553..092eb70c06 100644 +--- a/src/runtime/internal/atomic/atomic_loong64.s ++++ b/src/runtime/internal/atomic/atomic_loong64.s +@@ -191,13 +191,7 @@ TEXT ·Or8(SB), NOSPLIT, $0-9 + SLLV $3, R7 + // Shift val for aligned ptr. R5 = val << R4 + SLLV R7, R5 +- +- DBAR +- LL (R6), R7 +- OR R5, R7 +- SC R7, (R6) +- BEQ R7, -4(PC) +- DBAR ++ AMORW R5, (R6), R0 + RET + + // void And8(byte volatile*, byte); +@@ -216,37 +210,21 @@ TEXT ·And8(SB), NOSPLIT, $0-9 + SLLV R7, R8 + NOR R0, R8 + OR R8, R5 +- +- DBAR +- LL (R6), R7 +- AND R5, R7 +- SC R7, (R6) +- BEQ R7, -4(PC) +- DBAR ++ AMANDW R5, (R6), R0 + RET + + // func Or(addr *uint32, v uint32) + TEXT ·Or(SB), NOSPLIT, $0-12 + MOVV ptr+0(FP), R4 + MOVW val+8(FP), R5 +- DBAR +- LL (R4), R6 +- OR R5, R6 +- SC R6, (R4) +- BEQ R6, -4(PC) +- DBAR ++ AMORW R5, (R4), R0 + RET + + // func And(addr *uint32, v uint32) + TEXT ·And(SB), NOSPLIT, $0-12 + MOVV ptr+0(FP), R4 + MOVW val+8(FP), R5 +- DBAR +- LL (R4), R6 +- AND R5, R6 +- SC R6, (R4) +- BEQ R6, -4(PC) +- DBAR ++ AMANDW R5, (R4), R0 + RET + + // uint32 runtime∕internal∕atomic·Load(uint32 volatile* ptr) +-- +2.20.1 + diff --git a/loongarch64/0013-cmd-compiler-runtime-internal-atomic-Implementing-xc.patch b/loongarch64/0013-cmd-compiler-runtime-internal-atomic-Implementing-xc.patch new file mode 100644 index 0000000000000000000000000000000000000000..483a868ab7c08cec9325b98f701af580dc9cd0f4 --- /dev/null +++ b/loongarch64/0013-cmd-compiler-runtime-internal-atomic-Implementing-xc.patch @@ -0,0 +1,53 @@ +From e544c679d934cc5e79f8d83495828549d38e8ea6 Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Thu, 15 Jun 2023 12:34:55 +0800 +Subject: [PATCH 13/51] cmd/compiler,runtime/internal/atomic: Implementing + xchg{,64} using amswapdb{w,d} on loong64 + +Change-Id: Ib8acb6f0f1a91e50c67064dae19c085f01341e08 +--- + src/cmd/compile/internal/loong64/ssa.go | 4 ++-- + src/runtime/internal/atomic/atomic_loong64.s | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/src/cmd/compile/internal/loong64/ssa.go b/src/cmd/compile/internal/loong64/ssa.go +index 8d305c4f57..74489fe13a 100644 +--- a/src/cmd/compile/internal/loong64/ssa.go ++++ b/src/cmd/compile/internal/loong64/ssa.go +@@ -496,9 +496,9 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) { + s.Prog(loong64.ADBAR) + case ssa.OpLOONG64LoweredAtomicExchange32, ssa.OpLOONG64LoweredAtomicExchange64: + // AMSWAPx Rarg1, (Rarg0), Rout +- amswapx := loong64.AAMSWAPV ++ amswapx := loong64.AAMSWAPDBV + if v.Op == ssa.OpLOONG64LoweredAtomicExchange32 { +- amswapx = loong64.AAMSWAPW ++ amswapx = loong64.AAMSWAPDBW + } + p := s.Prog(amswapx) + p.From.Type = obj.TYPE_REG +diff --git a/src/runtime/internal/atomic/atomic_loong64.s b/src/runtime/internal/atomic/atomic_loong64.s +index 092eb70c06..215bb0382c 100644 +--- a/src/runtime/internal/atomic/atomic_loong64.s ++++ b/src/runtime/internal/atomic/atomic_loong64.s +@@ -120,7 +120,7 @@ TEXT ·Xadd64(SB), NOSPLIT, $0-24 + TEXT ·Xchg(SB), NOSPLIT, $0-20 + MOVV ptr+0(FP), R4 + MOVW new+8(FP), R5 +- AMSWAPW R5, (R4), R6 ++ AMSWAPDBW R5, (R4), R6 + MOVW R6, ret+16(FP) + RET + +@@ -128,7 +128,7 @@ TEXT ·Xchg(SB), NOSPLIT, $0-20 + TEXT ·Xchg64(SB), NOSPLIT, $0-24 + MOVV ptr+0(FP), R4 + MOVV new+8(FP), R5 +- AMSWAPV R5, (R4), R6 ++ AMSWAPDBV R5, (R4), R6 + MOVV R6, ret+16(FP) + RET + +-- +2.20.1 + diff --git a/loongarch64/0014-cmd-compiler-runtime-internal-atomic-Implementing-xa.patch b/loongarch64/0014-cmd-compiler-runtime-internal-atomic-Implementing-xa.patch new file mode 100644 index 0000000000000000000000000000000000000000..c6f99da0d0e705ca17e5ce0fe88c4646f8ac47e5 --- /dev/null +++ b/loongarch64/0014-cmd-compiler-runtime-internal-atomic-Implementing-xa.patch @@ -0,0 +1,54 @@ +From f8f3410e4f5a69431fcac7cc336553d9d8aaf05b Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Thu, 15 Jun 2023 12:37:00 +0800 +Subject: [PATCH 14/51] cmd/compiler,runtime/internal/atomic: Implementing + xadd{,64} using amadddb{w,d} on loong64 + +Change-Id: If58d4bcc1b367af5daf9f753bde61de4a7f690f1 +--- + src/cmd/compile/internal/loong64/ssa.go | 4 ++-- + src/runtime/internal/atomic/atomic_loong64.s | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/src/cmd/compile/internal/loong64/ssa.go b/src/cmd/compile/internal/loong64/ssa.go +index 74489fe13a..0e8683ba81 100644 +--- a/src/cmd/compile/internal/loong64/ssa.go ++++ b/src/cmd/compile/internal/loong64/ssa.go +@@ -518,10 +518,10 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) { + case ssa.OpLOONG64LoweredAtomicAdd32, ssa.OpLOONG64LoweredAtomicAdd64: + // AMADDx Rarg1, (Rarg0), Rout + // ADDxU Rarg1, Rout, Rout +- amaddx := loong64.AAMADDV ++ amaddx := loong64.AAMADDDBV + addx := loong64.AADDVU + if v.Op == ssa.OpLOONG64LoweredAtomicAdd32 { +- amaddx = loong64.AAMADDW ++ amaddx = loong64.AAMADDDBW + addx = loong64.AADDU + } + p := s.Prog(amaddx) +diff --git a/src/runtime/internal/atomic/atomic_loong64.s b/src/runtime/internal/atomic/atomic_loong64.s +index 215bb0382c..1ea85b1944 100644 +--- a/src/runtime/internal/atomic/atomic_loong64.s ++++ b/src/runtime/internal/atomic/atomic_loong64.s +@@ -102,7 +102,7 @@ TEXT ·Casp1(SB), NOSPLIT, $0-25 + TEXT ·Xadd(SB), NOSPLIT, $0-20 + MOVV ptr+0(FP), R4 + MOVW delta+8(FP), R5 +- AMADDW R5, (R4), R6 ++ AMADDDBW R5, (R4), R6 + ADDU R6, R5, R4 + MOVW R4, ret+16(FP) + RET +@@ -111,7 +111,7 @@ TEXT ·Xadd(SB), NOSPLIT, $0-20 + TEXT ·Xadd64(SB), NOSPLIT, $0-24 + MOVV ptr+0(FP), R4 + MOVV delta+8(FP), R5 +- AMADDV R5, (R4), R6 ++ AMADDDBV R5, (R4), R6 + ADDVU R6, R5, R4 + MOVV R4, ret+16(FP) + RET +-- +2.20.1 + diff --git a/loongarch64/0015-cmd-compiler-runtime-internal-atomic-Implementing-An.patch b/loongarch64/0015-cmd-compiler-runtime-internal-atomic-Implementing-An.patch new file mode 100644 index 0000000000000000000000000000000000000000..e98665d3cf5719ba02ca91c65faddd25426472fa --- /dev/null +++ b/loongarch64/0015-cmd-compiler-runtime-internal-atomic-Implementing-An.patch @@ -0,0 +1,91 @@ +From 73d7ba6ee8b68502a1c917cb45c0d961df151fa5 Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Thu, 15 Jun 2023 12:40:55 +0800 +Subject: [PATCH 15/51] cmd/compiler,runtime/internal/atomic: Implementing + {And,Or}{32,8} using am{and,or}dbw on loong64 + +Change-Id: Ic5ce31d240ef04f09e9c00623b0a7aa799cd7bf4 +--- + src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go | 4 ++-- + src/cmd/compile/internal/ssa/opGen.go | 4 ++-- + src/runtime/internal/atomic/atomic_loong64.s | 8 ++++---- + 3 files changed, 8 insertions(+), 8 deletions(-) + +diff --git a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go +index 41cc431e8b..ce08346a4a 100644 +--- a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go ++++ b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go +@@ -382,8 +382,8 @@ func init() { + + // Atomic 32 bit AND/OR. + // *arg0 &= (|=) arg1. arg2=mem. returns nil. +- {name: "LoweredAtomicAnd32", argLength: 3, reg: gpxchg, asm: "AMANDW", faultOnNilArg0: true, hasSideEffects: true}, +- {name: "LoweredAtomicOr32", argLength: 3, reg: gpxchg, asm: "AMORW", faultOnNilArg0: true, hasSideEffects: true}, ++ {name: "LoweredAtomicAnd32", argLength: 3, reg: gpxchg, asm: "AMANDDBW", faultOnNilArg0: true, hasSideEffects: true}, ++ {name: "LoweredAtomicOr32", argLength: 3, reg: gpxchg, asm: "AMORDBW", faultOnNilArg0: true, hasSideEffects: true}, + + // atomic add. + // *arg0 += arg1. arg2=mem. returns . +diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go +index 55a42ae782..fc735c48b5 100644 +--- a/src/cmd/compile/internal/ssa/opGen.go ++++ b/src/cmd/compile/internal/ssa/opGen.go +@@ -24451,7 +24451,7 @@ var opcodeTable = [...]opInfo{ + argLen: 3, + faultOnNilArg0: true, + hasSideEffects: true, +- asm: loong64.AAMANDW, ++ asm: loong64.AAMANDDBW, + reg: regInfo{ + inputs: []inputInfo{ + {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 +@@ -24467,7 +24467,7 @@ var opcodeTable = [...]opInfo{ + argLen: 3, + faultOnNilArg0: true, + hasSideEffects: true, +- asm: loong64.AAMORW, ++ asm: loong64.AAMORDBW, + reg: regInfo{ + inputs: []inputInfo{ + {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 +diff --git a/src/runtime/internal/atomic/atomic_loong64.s b/src/runtime/internal/atomic/atomic_loong64.s +index 1ea85b1944..7eee52ddb8 100644 +--- a/src/runtime/internal/atomic/atomic_loong64.s ++++ b/src/runtime/internal/atomic/atomic_loong64.s +@@ -191,7 +191,7 @@ TEXT ·Or8(SB), NOSPLIT, $0-9 + SLLV $3, R7 + // Shift val for aligned ptr. R5 = val << R4 + SLLV R7, R5 +- AMORW R5, (R6), R0 ++ AMORDBW R5, (R6), R0 + RET + + // void And8(byte volatile*, byte); +@@ -210,21 +210,21 @@ TEXT ·And8(SB), NOSPLIT, $0-9 + SLLV R7, R8 + NOR R0, R8 + OR R8, R5 +- AMANDW R5, (R6), R0 ++ AMANDDBW R5, (R6), R0 + RET + + // func Or(addr *uint32, v uint32) + TEXT ·Or(SB), NOSPLIT, $0-12 + MOVV ptr+0(FP), R4 + MOVW val+8(FP), R5 +- AMORW R5, (R4), R0 ++ AMORDBW R5, (R4), R0 + RET + + // func And(addr *uint32, v uint32) + TEXT ·And(SB), NOSPLIT, $0-12 + MOVV ptr+0(FP), R4 + MOVW val+8(FP), R5 +- AMANDW R5, (R4), R0 ++ AMANDDBW R5, (R4), R0 + RET + + // uint32 runtime∕internal∕atomic·Load(uint32 volatile* ptr) +-- +2.20.1 + diff --git a/loongarch64/0016-cmd-internal-obj-loong64-remove-the-invalid-plan9-fo.patch b/loongarch64/0016-cmd-internal-obj-loong64-remove-the-invalid-plan9-fo.patch new file mode 100644 index 0000000000000000000000000000000000000000..b77aa1c7efde2c1d523b53e101f7b5aae186dcfc --- /dev/null +++ b/loongarch64/0016-cmd-internal-obj-loong64-remove-the-invalid-plan9-fo.patch @@ -0,0 +1,177 @@ +From 24c0f0e52039b9b8f2e0ab8f465f6e1c03412ae9 Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Mon, 8 May 2023 06:20:21 +0800 +Subject: [PATCH 16/51] cmd/internal/obj/loong64: remove the invalid plan9 + format of the BREAK instruction + +In the three formats corresponding to case 7 of the function asmout, BREAK actually +corresponds to the cacop instruction of Loong64, refer to the loong64 instruction +manual volume 1 [1], the cacop instruction is a privileged instruction used to +maintain the cache, and the user mode does not have permission to execute. + +Referring to the loong64 instruction manual volume 1 [1], the format of SYSCALL, +BREAK, DBAR and NOOP instructions is similar and can be grouped into one category. + +[1]: https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html + +Change-Id: I0b8998270102d1557fc2b2410cf8c0b078bd0c2e +--- + .../asm/internal/asm/testdata/loong64enc1.s | 2 - + src/cmd/internal/obj/loong64/asm.go | 51 ++++++++++--------- + 2 files changed, 27 insertions(+), 26 deletions(-) + +diff --git a/src/cmd/asm/internal/asm/testdata/loong64enc1.s b/src/cmd/asm/internal/asm/testdata/loong64enc1.s +index 288408b010..701515cf4c 100644 +--- a/src/cmd/asm/internal/asm/testdata/loong64enc1.s ++++ b/src/cmd/asm/internal/asm/testdata/loong64enc1.s +@@ -141,8 +141,6 @@ lable2: + MOVV R4, F5 // 85a81401 + MOVV F4, R5 // 85b81401 + WORD $74565 // 45230100 +- BREAK R4, result+16(FP) // 64600006 +- BREAK R4, 1(R5) // a4040006 + BREAK // 00002a00 + UNDEF // 00002a00 + +diff --git a/src/cmd/internal/obj/loong64/asm.go b/src/cmd/internal/obj/loong64/asm.go +index 638bd1139f..77eaa628e8 100644 +--- a/src/cmd/internal/obj/loong64/asm.go ++++ b/src/cmd/internal/obj/loong64/asm.go +@@ -354,11 +354,6 @@ var optab = []Optab{ + {ATEQ, C_SCON, C_REG, C_NONE, C_REG, C_NONE, 15, 8, 0, 0}, + {ATEQ, C_SCON, C_NONE, C_NONE, C_REG, C_NONE, 15, 8, 0, 0}, + +- {ABREAK, C_REG, C_NONE, C_NONE, C_SEXT, C_NONE, 7, 4, 0, 0}, // really CACHE instruction +- {ABREAK, C_REG, C_NONE, C_NONE, C_SAUTO, C_NONE, 7, 4, REGSP, 0}, +- {ABREAK, C_REG, C_NONE, C_NONE, C_SOREG, C_NONE, 7, 4, REGZERO, 0}, +- {ABREAK, C_NONE, C_NONE, C_NONE, C_NONE, C_NONE, 5, 4, 0, 0}, +- + {ARDTIMELW, C_NONE, C_NONE, C_NONE, C_REG, C_REG, 62, 4, 0, 0}, + {ARDTIMEHW, C_NONE, C_NONE, C_NONE, C_REG, C_REG, 62, 4, 0, 0}, + {ARDTIMED, C_NONE, C_NONE, C_NONE, C_REG, C_REG, 62, 4, 0, 0}, +@@ -601,7 +596,7 @@ func span0(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { + v := pcAlignPadLength(c.ctxt, p.Pc, alignedValue) + for i = 0; i < int32(v/4); i++ { + // emit ANOOP instruction by the padding size +- c.ctxt.Arch.ByteOrder.PutUint32(bp, c.oprrr(ANOOP)) ++ c.ctxt.Arch.ByteOrder.PutUint32(bp, c.opi(ANOOP)) + bp = bp[4:] + } + continue +@@ -1165,6 +1160,7 @@ func buildop(ctxt *obj.Link) { + case ASYSCALL: + opset(ADBAR, r0) + opset(ANOOP, r0) ++ opset(ABREAK, r0) + + case ACMPEQF: + opset(ACMPGTF, r0) +@@ -1186,7 +1182,6 @@ func buildop(ctxt *obj.Link) { + AMOVD, + AMOVF, + AMOVV, +- ABREAK, + ARFE, + AJAL, + AJMP, +@@ -1272,6 +1267,10 @@ func OP_IR(op uint32, i uint32, r2 uint32) uint32 { + return op | (i&0xFFFFF)<<5 | (r2&0x1F)<<0 // ui20, rd5 + } + ++func OP_I(op uint32, i uint32) uint32 { ++ return op | (i&0x7FFF)<<0 ++} ++ + // Encoding for the 'b' or 'bl' instruction. + func OP_B_BL(op uint32, i uint32) uint32 { + return op | ((i & 0xFFFF) << 10) | ((i >> 16) & 0x3FF) +@@ -1337,7 +1336,7 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) { + o1 = OP_12IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.To.Reg)) + + case 5: // syscall +- o1 = c.oprrr(p.As) ++ o1 = c.opi(p.As) + + case 6: // beq r1,[r2],sbra + v := int32(0) +@@ -1481,7 +1480,7 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) { + } else { // ATNE + o1 = OP_16IRR(c.opirr(ABEQ), uint32(2), uint32(r), uint32(p.To.Reg)) + } +- o2 = c.oprrr(ABREAK) | (uint32(v) & 0x7FFF) ++ o2 = OP_I(c.opi(ABREAK), uint32(v)) + + case 16: // sll $c,[r1],r2 + v := c.regoff(&p.From) +@@ -1652,7 +1651,7 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) { + o1 = OP_RR(a, uint32(p.From.Reg), uint32(p.To.Reg)) + + case 49: // undef +- o1 = c.oprrr(ABREAK) ++ o1 = c.opi(ABREAK) + + // relocation operations + case 50: // mov r,addr ==> pcalau12i + sw +@@ -1972,10 +1971,6 @@ func (c *ctxt0) oprrr(a obj.As) uint32 { + case AJAL: + return (0x13 << 26) | 1 // jirl r1, rj, 0 + +- case ABREAK: +- return 0x54 << 15 +- case ASYSCALL: +- return 0x56 << 15 + case ADIVF: + return 0x20d << 15 + case ADIVD: +@@ -2049,12 +2044,6 @@ func (c *ctxt0) oprrr(a obj.As) uint32 { + return 0x4511 << 10 + case ASQRTD: + return 0x4512 << 10 +- +- case ADBAR: +- return 0x70e4 << 15 +- case ANOOP: +- // andi r0, r0, 0 +- return 0x03400000 + } + + if a < 0 { +@@ -2083,6 +2072,24 @@ func (c *ctxt0) oprr(a obj.As) uint32 { + return 0 + } + ++func (c *ctxt0) opi(a obj.As) uint32 { ++ switch a { ++ case ASYSCALL: ++ return 0x56 << 15 ++ case ABREAK: ++ return 0x54 << 15 ++ case ADBAR: ++ return 0x70e4 << 15 ++ case ANOOP: ++ // andi r0, r0, 0 ++ return 0x03400000 ++ } ++ ++ c.ctxt.Diag("bad ic opcode %v", a) ++ ++ return 0 ++} ++ + func (c *ctxt0) opir(a obj.As) uint32 { + switch a { + case ALU12IW: +@@ -2179,10 +2186,6 @@ func (c *ctxt0) opirr(a obj.As) uint32 { + return 0x0be << 22 + case AMOVVR: + return 0x0bf << 22 +- +- case ABREAK: +- return 0x018 << 22 +- + case -AMOVWL: + return 0x0b8 << 22 + case -AMOVWR: +-- +2.20.1 + diff --git a/loongarch64/0017-cmd-internal-obj-loong64-correct-the-instruction-for.patch b/loongarch64/0017-cmd-internal-obj-loong64-correct-the-instruction-for.patch new file mode 100644 index 0000000000000000000000000000000000000000..ee25a37b2527df027a34b74a6484baaacd41a458 --- /dev/null +++ b/loongarch64/0017-cmd-internal-obj-loong64-correct-the-instruction-for.patch @@ -0,0 +1,75 @@ +From 104b5abb0bb5c5a54a8e3940db1ca5f185ff70f9 Mon Sep 17 00:00:00 2001 +From: chenguoqi +Date: Thu, 27 Jul 2023 11:01:16 +0800 +Subject: [PATCH 17/51] cmd/internal/obj/loong64: correct the instruction + format of plan9 assembly NOOP + +Change-Id: Icbaa925775d8fb8978a6e0cf7caa1f4be8ebf7f4 +--- + src/cmd/internal/obj/loong64/asm.go | 27 +++++++++++++++++++++------ + 1 file changed, 21 insertions(+), 6 deletions(-) + +diff --git a/src/cmd/internal/obj/loong64/asm.go b/src/cmd/internal/obj/loong64/asm.go +index 77eaa628e8..c6c28002d1 100644 +--- a/src/cmd/internal/obj/loong64/asm.go ++++ b/src/cmd/internal/obj/loong64/asm.go +@@ -596,7 +596,7 @@ func span0(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { + v := pcAlignPadLength(c.ctxt, p.Pc, alignedValue) + for i = 0; i < int32(v/4); i++ { + // emit ANOOP instruction by the padding size +- c.ctxt.Arch.ByteOrder.PutUint32(bp, c.opi(ANOOP)) ++ c.ctxt.Arch.ByteOrder.PutUint32(bp, c.op0(ANOOP)) + bp = bp[4:] + } + continue +@@ -1336,7 +1336,13 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) { + o1 = OP_12IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.To.Reg)) + + case 5: // syscall +- o1 = c.opi(p.As) ++ switch p.As { ++ case ANOOP: ++ o1 = c.op0(p.As) ++ default: ++ v := c.regoff(&p.From) ++ o1 = OP_I(c.opi(p.As), uint32(v)) ++ } + + case 6: // beq r1,[r2],sbra + v := int32(0) +@@ -2072,6 +2078,18 @@ func (c *ctxt0) oprr(a obj.As) uint32 { + return 0 + } + ++func (c *ctxt0) op0(a obj.As) uint32 { ++ switch a { ++ case ANOOP: ++ // andi r0, r0, 0 ++ return 0x03400000 ++ } ++ ++ c.ctxt.Diag("bad op0 opcode %v", a) ++ ++ return 0 ++} ++ + func (c *ctxt0) opi(a obj.As) uint32 { + switch a { + case ASYSCALL: +@@ -2080,12 +2098,9 @@ func (c *ctxt0) opi(a obj.As) uint32 { + return 0x54 << 15 + case ADBAR: + return 0x70e4 << 15 +- case ANOOP: +- // andi r0, r0, 0 +- return 0x03400000 + } + +- c.ctxt.Diag("bad ic opcode %v", a) ++ c.ctxt.Diag("bad opi opcode %v", a) + + return 0 + } +-- +2.20.1 + diff --git a/loongarch64/0018-cmd-internal-obj-loong64-recheck-jump-offset-boundar.patch b/loongarch64/0018-cmd-internal-obj-loong64-recheck-jump-offset-boundar.patch new file mode 100644 index 0000000000000000000000000000000000000000..c257cf57ac46d8e08255737f2ed7d587f2005641 --- /dev/null +++ b/loongarch64/0018-cmd-internal-obj-loong64-recheck-jump-offset-boundar.patch @@ -0,0 +1,101 @@ +From e35699ad7d0078e2be2f677e33984bb8af841d28 Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Wed, 16 Aug 2023 02:09:49 +0800 +Subject: [PATCH 18/51] cmd/internal/obj/loong64: recheck jump offset boundary + after auto-aligning loop heads + +After the alignment of the loop header is performed, the offset of the checked +conditional branch instruction may overflow, so it needs to be checked again. + +When checking whether the offset of the branch jump instruction overflows, it +can be classified and processed according to the range of the immediate field +of the specific instruction, which can reduce the introduction of unnecessary +jump instructions. + +Fixes #61819 + +Change-Id: Ica4c4ade43bf106c7035a1c02b89d3347a414b41 +--- + src/cmd/internal/obj/loong64/asm.go | 30 +++++++++++++++++++---------- + 1 file changed, 20 insertions(+), 10 deletions(-) + +diff --git a/src/cmd/internal/obj/loong64/asm.go b/src/cmd/internal/obj/loong64/asm.go +index c6c28002d1..74ee2b6cea 100644 +--- a/src/cmd/internal/obj/loong64/asm.go ++++ b/src/cmd/internal/obj/loong64/asm.go +@@ -491,11 +491,8 @@ func span0(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { + } + + // Run these passes until convergence. +- bflag := 1 +- var otxt int64 +- var q *obj.Prog +- for bflag != 0 { +- bflag = 0 ++ for { ++ rescan := false + pc = 0 + prev := c.cursym.Func().Text + for p = prev.Link; p != nil; prev, p = p, p.Link { +@@ -510,7 +507,7 @@ func span0(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { + // because pc will be adjusted if padding happens. + if p.Mark&branchLoopHead != 0 && pc&(loopAlign-1) != 0 && + !(prev.As == obj.APCALIGN && prev.From.Offset >= loopAlign) { +- q = c.newprog() ++ q := c.newprog() + prev.Link = q + q.Link = p + q.Pc = pc +@@ -526,6 +523,7 @@ func span0(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { + // since this loop iteration is for p. + pc += int64(pcAlignPadLength(ctxt, pc, loopAlign)) + p.Pc = pc ++ rescan = true + } + + // very large conditional branches +@@ -535,9 +533,16 @@ func span0(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { + // generate extra passes putting branches + // around jmps to fix. this is rare. + if o.type_ == 6 && p.To.Target() != nil { +- otxt = p.To.Target().Pc - pc +- if otxt < -(1<<17)+10 || otxt >= (1<<17)-10 { +- q = c.newprog() ++ otxt := p.To.Target().Pc - pc ++ bound := int64(1 << (18 - 1)) ++ ++ switch p.As { ++ case -ABEQ, -ABNE, ABFPT, ABFPF: ++ bound = int64(1 << (23 - 1)) ++ } ++ ++ if otxt < -bound || otxt >= bound { ++ q := c.newprog() + q.Link = p.Link + p.Link = q + q.As = AJMP +@@ -552,7 +557,7 @@ func span0(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { + q.Pos = p.Pos + q.To.Type = obj.TYPE_BRANCH + q.To.SetTarget(q.Link.Link) +- bflag = 1 ++ rescan = true + } + } + +@@ -574,7 +579,12 @@ func span0(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { + } + + c.cursym.Size = pc ++ ++ if !rescan { ++ break ++ } + } ++ + pc += -pc & (FuncAlign - 1) + c.cursym.Size = pc + +-- +2.20.1 + diff --git a/loongarch64/0019-cmd-link-internal-loong64-correct-the-glibc-dynamic-.patch b/loongarch64/0019-cmd-link-internal-loong64-correct-the-glibc-dynamic-.patch new file mode 100644 index 0000000000000000000000000000000000000000..e4d0bf063facf7b4c5a67779721b910f5d739c01 --- /dev/null +++ b/loongarch64/0019-cmd-link-internal-loong64-correct-the-glibc-dynamic-.patch @@ -0,0 +1,29 @@ +From f7fcdefa21dfad1f275af660d431979cb45b0c7a Mon Sep 17 00:00:00 2001 +From: limeidan +Date: Wed, 6 Sep 2023 17:09:35 +0800 +Subject: [PATCH 19/51] cmd/link/internal/loong64: correct the glibc dynamic + linker path. + +Ref: https://loongson.github.io/LoongArch-Documentation/LoongArch-ELF-ABI-EN.html#_program_interpreter_path + +Change-Id: Ic2598110cc091362cb09f877b6b86433cacf32c6 +--- + src/cmd/link/internal/loong64/obj.go | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/cmd/link/internal/loong64/obj.go b/src/cmd/link/internal/loong64/obj.go +index c3f6ed9386..fd193a2445 100644 +--- a/src/cmd/link/internal/loong64/obj.go ++++ b/src/cmd/link/internal/loong64/obj.go +@@ -29,7 +29,7 @@ func Init() (*sys.Arch, ld.Arch) { + Gentext: gentext, + + ELF: ld.ELFArch{ +- Linuxdynld: "/lib64/ld.so.1", ++ Linuxdynld: "/lib64/ld-linux-loongarch-lp64d.so.1", + LinuxdynldMusl: "/lib64/ld-musl-loongarch.so.1", + Freebsddynld: "XXX", + Openbsddynld: "XXX", +-- +2.20.1 + diff --git a/loongarch64/0020-cmd-link-internal-loadelf-correct-the-relocation-siz.patch b/loongarch64/0020-cmd-link-internal-loadelf-correct-the-relocation-siz.patch new file mode 100644 index 0000000000000000000000000000000000000000..50a9f55c144174a5c3be60c939058ea42b15479c --- /dev/null +++ b/loongarch64/0020-cmd-link-internal-loadelf-correct-the-relocation-siz.patch @@ -0,0 +1,33 @@ +From 031ca97dc3f0e80e52ec4914ec0bfc9f7d491727 Mon Sep 17 00:00:00 2001 +From: limeidan +Date: Thu, 14 Sep 2023 20:11:07 +0800 +Subject: [PATCH 20/51] cmd/link/internal/loadelf: correct the relocation size + of R_LARCH_64 + +Change-Id: If3eaca8b92e8f5265c7763d13021a6353b9df9b6 +--- + src/cmd/link/internal/loadelf/ldelf.go | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/cmd/link/internal/loadelf/ldelf.go b/src/cmd/link/internal/loadelf/ldelf.go +index 942d54c06c..5ab7cf2204 100644 +--- a/src/cmd/link/internal/loadelf/ldelf.go ++++ b/src/cmd/link/internal/loadelf/ldelf.go +@@ -1012,11 +1012,13 @@ func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, uint8, error) { + LOONG64 | uint32(elf.R_LARCH_SOP_PUSH_ABSOLUTE)<<16, + LOONG64 | uint32(elf.R_LARCH_MARK_LA)<<16, + LOONG64 | uint32(elf.R_LARCH_SOP_POP_32_S_0_10_10_16_S2)<<16, +- LOONG64 | uint32(elf.R_LARCH_64)<<16, + LOONG64 | uint32(elf.R_LARCH_MARK_PCREL)<<16, + LOONG64 | uint32(elf.R_LARCH_32_PCREL)<<16: + return 4, 4, nil + ++ case LOONG64 | uint32(elf.R_LARCH_64)<<16: ++ return 8, 8, nil ++ + case S390X | uint32(elf.R_390_8)<<16: + return 1, 1, nil + +-- +2.20.1 + diff --git a/loongarch64/0021-cmd-compile-cmd-internal-runtime-change-the-register.patch b/loongarch64/0021-cmd-compile-cmd-internal-runtime-change-the-register.patch new file mode 100644 index 0000000000000000000000000000000000000000..27c326e741690633d71897fbc459f2ac6246d984 --- /dev/null +++ b/loongarch64/0021-cmd-compile-cmd-internal-runtime-change-the-register.patch @@ -0,0 +1,3011 @@ +From 4d56cbfdfd29e4eb9ac86bca7e1db5b8794005ec Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Thu, 17 Aug 2023 03:58:10 +0800 +Subject: [PATCH 21/51] cmd/compile, cmd/internal, runtime: change the + registers used by the duff device for loong64 + +Add R21 to the allocatable registers, use R20 and R21 in duff +device. This CL is in preparation for subsequent regABI support. + +Updates #40724 + +Co-authored-by: Xiaolin Zhao +Change-Id: I6d18e94a96e7598f0700855fd07ae7c3ad86737d +--- + src/cmd/compile/internal/loong64/ssa.go | 2 +- + .../compile/internal/ssa/_gen/LOONG64Ops.go | 44 +- + src/cmd/compile/internal/ssa/opGen.go | 438 +++--- + src/cmd/internal/obj/loong64/a.out.go | 8 +- + src/runtime/duff_loong64.s | 1280 ++++++++--------- + src/runtime/mkduff.go | 10 +- + 6 files changed, 891 insertions(+), 891 deletions(-) + +diff --git a/src/cmd/compile/internal/loong64/ssa.go b/src/cmd/compile/internal/loong64/ssa.go +index 0e8683ba81..199fd4ce33 100644 +--- a/src/cmd/compile/internal/loong64/ssa.go ++++ b/src/cmd/compile/internal/loong64/ssa.go +@@ -362,7 +362,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) { + p.To.Type = obj.TYPE_REG + p.To.Reg = v.Reg() + case ssa.OpLOONG64DUFFZERO: +- // runtime.duffzero expects start address in R19 ++ // runtime.duffzero expects start address in R20 + p := s.Prog(obj.ADUFFZERO) + p.To.Type = obj.TYPE_MEM + p.To.Name = obj.NAME_EXTERN +diff --git a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go +index ce08346a4a..9950619baf 100644 +--- a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go ++++ b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go +@@ -123,7 +123,7 @@ func init() { + + // Common individual register masks + var ( +- gp = buildReg("R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31") // R1 is LR, R2 is thread pointer, R3 is stack pointer, R21-unused, R22 is g, R30 is REGTMP ++ gp = buildReg("R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31") // R1 is LR, R2 is thread pointer, R3 is stack pointer, R22 is g, R30 is REGTMP + gpg = gp | buildReg("g") + gpsp = gp | buildReg("SP") + gpspg = gpg | buildReg("SP") +@@ -283,21 +283,21 @@ func init() { + // arg1 = mem + // auxint = offset into duffzero code to start executing + // returns mem +- // R19 aka loong64.REGRT1 changed as side effect ++ // R20 aka loong64.REGRT1 changed as side effect + { + name: "DUFFZERO", + aux: "Int64", + argLength: 2, + reg: regInfo{ +- inputs: []regMask{buildReg("R19")}, +- clobbers: buildReg("R19 R1"), ++ inputs: []regMask{buildReg("R20")}, ++ clobbers: buildReg("R20 R1"), + }, + faultOnNilArg0: true, + }, + + // duffcopy +- // arg0 = address of dst memory (in R20, changed as side effect) REGRT2 +- // arg1 = address of src memory (in R19, changed as side effect) REGRT1 ++ // arg0 = address of dst memory (in R21, changed as side effect) REGRT2 ++ // arg1 = address of src memory (in R20, changed as side effect) REGRT1 + // arg2 = mem + // auxint = offset into duffcopy code to start executing + // returns mem +@@ -306,53 +306,53 @@ func init() { + aux: "Int64", + argLength: 3, + reg: regInfo{ +- inputs: []regMask{buildReg("R20"), buildReg("R19")}, +- clobbers: buildReg("R19 R20 R1"), ++ inputs: []regMask{buildReg("R21"), buildReg("R20")}, ++ clobbers: buildReg("R20 R21 R1"), + }, + faultOnNilArg0: true, + faultOnNilArg1: true, + }, + + // large or unaligned zeroing +- // arg0 = address of memory to zero (in R19, changed as side effect) ++ // arg0 = address of memory to zero (in R20, changed as side effect) + // arg1 = address of the last element to zero + // arg2 = mem + // auxint = alignment + // returns mem +- // MOVx R0, (R19) +- // ADDV $sz, R19 +- // BGEU Rarg1, R19, -2(PC) ++ // MOVx R0, (R20) ++ // ADDV $sz, R20 ++ // BGEU Rarg1, R20, -2(PC) + { + name: "LoweredZero", + aux: "Int64", + argLength: 3, + reg: regInfo{ +- inputs: []regMask{buildReg("R19"), gp}, +- clobbers: buildReg("R19"), ++ inputs: []regMask{buildReg("R20"), gp}, ++ clobbers: buildReg("R20"), + }, + typ: "Mem", + faultOnNilArg0: true, + }, + + // large or unaligned move +- // arg0 = address of dst memory (in R20, changed as side effect) +- // arg1 = address of src memory (in R19, changed as side effect) ++ // arg0 = address of dst memory (in R21, changed as side effect) ++ // arg1 = address of src memory (in R20, changed as side effect) + // arg2 = address of the last element of src + // arg3 = mem + // auxint = alignment + // returns mem +- // MOVx (R19), Rtmp +- // MOVx Rtmp, (R20) +- // ADDV $sz, R19 ++ // MOVx (R20), Rtmp ++ // MOVx Rtmp, (R21) + // ADDV $sz, R20 +- // BGEU Rarg2, R19, -4(PC) ++ // ADDV $sz, R21 ++ // BGEU Rarg2, R20, -4(PC) + { + name: "LoweredMove", + aux: "Int64", + argLength: 4, + reg: regInfo{ +- inputs: []regMask{buildReg("R20"), buildReg("R19"), gp}, +- clobbers: buildReg("R19 R20"), ++ inputs: []regMask{buildReg("R21"), buildReg("R20"), gp}, ++ clobbers: buildReg("R20 R21"), + }, + typ: "Mem", + faultOnNilArg0: true, +diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go +index fc735c48b5..2c17801ea4 100644 +--- a/src/cmd/compile/internal/ssa/opGen.go ++++ b/src/cmd/compile/internal/ssa/opGen.go +@@ -22910,11 +22910,11 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AADDVU, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 +- {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -22925,10 +22925,10 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AADDVU, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1072693244}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1073741820}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -22938,11 +22938,11 @@ var opcodeTable = [...]opInfo{ + asm: loong64.ASUBVU, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 +- {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -22953,10 +22953,10 @@ var opcodeTable = [...]opInfo{ + asm: loong64.ASUBVU, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -22967,11 +22967,11 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AMULV, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 +- {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -22982,11 +22982,11 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AMULHV, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 +- {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -22997,11 +22997,11 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AMULHVU, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 +- {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -23011,11 +23011,11 @@ var opcodeTable = [...]opInfo{ + asm: loong64.ADIVV, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 +- {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -23025,11 +23025,11 @@ var opcodeTable = [...]opInfo{ + asm: loong64.ADIVVU, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 +- {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -23039,11 +23039,11 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AREMV, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 +- {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -23053,11 +23053,11 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AREMVU, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 +- {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -23184,11 +23184,11 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AAND, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 +- {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -23199,10 +23199,10 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AAND, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -23213,11 +23213,11 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AOR, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 +- {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -23228,10 +23228,10 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AOR, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -23242,11 +23242,11 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AXOR, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 +- {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -23257,10 +23257,10 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AXOR, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -23271,11 +23271,11 @@ var opcodeTable = [...]opInfo{ + asm: loong64.ANOR, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 +- {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -23286,10 +23286,10 @@ var opcodeTable = [...]opInfo{ + asm: loong64.ANOR, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -23298,10 +23298,10 @@ var opcodeTable = [...]opInfo{ + argLen: 1, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -23363,11 +23363,11 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AMASKEQZ, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 +- {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -23377,11 +23377,11 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AMASKNEZ, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 +- {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -23391,11 +23391,11 @@ var opcodeTable = [...]opInfo{ + asm: loong64.ASLLV, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 +- {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -23406,10 +23406,10 @@ var opcodeTable = [...]opInfo{ + asm: loong64.ASLLV, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -23419,11 +23419,11 @@ var opcodeTable = [...]opInfo{ + asm: loong64.ASRLV, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 +- {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -23434,10 +23434,10 @@ var opcodeTable = [...]opInfo{ + asm: loong64.ASRLV, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -23447,11 +23447,11 @@ var opcodeTable = [...]opInfo{ + asm: loong64.ASRAV, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 +- {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -23462,10 +23462,10 @@ var opcodeTable = [...]opInfo{ + asm: loong64.ASRAV, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -23475,11 +23475,11 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AROTR, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 +- {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -23489,11 +23489,11 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AROTRV, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 +- {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -23504,10 +23504,10 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AROTR, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -23518,10 +23518,10 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AROTRV, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -23531,11 +23531,11 @@ var opcodeTable = [...]opInfo{ + asm: loong64.ASGT, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 +- {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -23546,10 +23546,10 @@ var opcodeTable = [...]opInfo{ + asm: loong64.ASGT, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -23559,11 +23559,11 @@ var opcodeTable = [...]opInfo{ + asm: loong64.ASGTU, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 +- {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -23574,10 +23574,10 @@ var opcodeTable = [...]opInfo{ + asm: loong64.ASGTU, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -23655,7 +23655,7 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AMOVV, + reg: regInfo{ + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -23695,7 +23695,7 @@ var opcodeTable = [...]opInfo{ + {0, 4611686018427387908}, // SP SB + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -23708,10 +23708,10 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AMOVB, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB ++ {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -23724,10 +23724,10 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AMOVBU, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB ++ {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -23740,10 +23740,10 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AMOVH, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB ++ {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -23756,10 +23756,10 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AMOVHU, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB ++ {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -23772,10 +23772,10 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AMOVW, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB ++ {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -23788,10 +23788,10 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AMOVWU, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB ++ {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -23804,10 +23804,10 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AMOVV, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB ++ {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -23820,7 +23820,7 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AMOVF, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB ++ {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB + }, + outputs: []outputInfo{ + {0, 4611686017353646080}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 +@@ -23836,7 +23836,7 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AMOVD, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB ++ {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB + }, + outputs: []outputInfo{ + {0, 4611686017353646080}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 +@@ -23852,8 +23852,8 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AMOVB, + reg: regInfo{ + inputs: []inputInfo{ +- {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 +- {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB ++ {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB + }, + }, + }, +@@ -23866,8 +23866,8 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AMOVH, + reg: regInfo{ + inputs: []inputInfo{ +- {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 +- {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB ++ {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB + }, + }, + }, +@@ -23880,8 +23880,8 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AMOVW, + reg: regInfo{ + inputs: []inputInfo{ +- {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 +- {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB ++ {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB + }, + }, + }, +@@ -23894,8 +23894,8 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AMOVV, + reg: regInfo{ + inputs: []inputInfo{ +- {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 +- {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB ++ {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB + }, + }, + }, +@@ -23908,7 +23908,7 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AMOVF, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB ++ {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB + {1, 4611686017353646080}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 + }, + }, +@@ -23922,7 +23922,7 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AMOVD, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB ++ {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB + {1, 4611686017353646080}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 + }, + }, +@@ -23936,7 +23936,7 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AMOVB, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB ++ {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB + }, + }, + }, +@@ -23949,7 +23949,7 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AMOVH, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB ++ {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB + }, + }, + }, +@@ -23962,7 +23962,7 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AMOVW, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB ++ {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB + }, + }, + }, +@@ -23975,7 +23975,7 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AMOVV, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB ++ {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB + }, + }, + }, +@@ -23985,10 +23985,10 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AMOVB, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -23998,10 +23998,10 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AMOVBU, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -24011,10 +24011,10 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AMOVH, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -24024,10 +24024,10 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AMOVHU, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -24037,10 +24037,10 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AMOVW, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -24050,10 +24050,10 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AMOVWU, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -24063,10 +24063,10 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AMOVV, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -24076,10 +24076,10 @@ var opcodeTable = [...]opInfo{ + resultInArg0: true, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -24220,7 +24220,7 @@ var opcodeTable = [...]opInfo{ + clobberFlags: true, + call: true, + reg: regInfo{ +- clobbers: 4611686018426339320, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 ++ clobbers: 4611686018427387896, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 + }, + }, + { +@@ -24231,7 +24231,7 @@ var opcodeTable = [...]opInfo{ + call: true, + tailCall: true, + reg: regInfo{ +- clobbers: 4611686018426339320, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 ++ clobbers: 4611686018427387896, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 + }, + }, + { +@@ -24243,9 +24243,9 @@ var opcodeTable = [...]opInfo{ + reg: regInfo{ + inputs: []inputInfo{ + {1, 268435456}, // R29 +- {0, 1070596092}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644668}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, +- clobbers: 4611686018426339320, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 ++ clobbers: 4611686018427387896, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 + }, + }, + { +@@ -24256,9 +24256,9 @@ var opcodeTable = [...]opInfo{ + call: true, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, +- clobbers: 4611686018426339320, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 ++ clobbers: 4611686018427387896, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 + }, + }, + { +@@ -24268,9 +24268,9 @@ var opcodeTable = [...]opInfo{ + faultOnNilArg0: true, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 262144}, // R19 ++ {0, 524288}, // R20 + }, +- clobbers: 262146, // R1 R19 ++ clobbers: 524290, // R1 R20 + }, + }, + { +@@ -24281,10 +24281,10 @@ var opcodeTable = [...]opInfo{ + faultOnNilArg1: true, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 524288}, // R20 +- {1, 262144}, // R19 ++ {0, 1048576}, // R21 ++ {1, 524288}, // R20 + }, +- clobbers: 786434, // R1 R19 R20 ++ clobbers: 1572866, // R1 R20 R21 + }, + }, + { +@@ -24294,10 +24294,10 @@ var opcodeTable = [...]opInfo{ + faultOnNilArg0: true, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 262144}, // R19 +- {1, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 524288}, // R20 ++ {1, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, +- clobbers: 262144, // R19 ++ clobbers: 524288, // R20 + }, + }, + { +@@ -24308,11 +24308,11 @@ var opcodeTable = [...]opInfo{ + faultOnNilArg1: true, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 524288}, // R20 +- {1, 262144}, // R19 +- {2, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1048576}, // R21 ++ {1, 524288}, // R20 ++ {2, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, +- clobbers: 786432, // R19 R20 ++ clobbers: 1572864, // R20 R21 + }, + }, + { +@@ -24321,10 +24321,10 @@ var opcodeTable = [...]opInfo{ + faultOnNilArg0: true, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB ++ {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -24334,10 +24334,10 @@ var opcodeTable = [...]opInfo{ + faultOnNilArg0: true, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB ++ {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -24347,10 +24347,10 @@ var opcodeTable = [...]opInfo{ + faultOnNilArg0: true, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB ++ {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -24361,8 +24361,8 @@ var opcodeTable = [...]opInfo{ + hasSideEffects: true, + reg: regInfo{ + inputs: []inputInfo{ +- {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 +- {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB ++ {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB + }, + }, + }, +@@ -24373,8 +24373,8 @@ var opcodeTable = [...]opInfo{ + hasSideEffects: true, + reg: regInfo{ + inputs: []inputInfo{ +- {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 +- {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB ++ {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB + }, + }, + }, +@@ -24385,8 +24385,8 @@ var opcodeTable = [...]opInfo{ + hasSideEffects: true, + reg: regInfo{ + inputs: []inputInfo{ +- {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 +- {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB ++ {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB + }, + }, + }, +@@ -24397,7 +24397,7 @@ var opcodeTable = [...]opInfo{ + hasSideEffects: true, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB ++ {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB + }, + }, + }, +@@ -24408,7 +24408,7 @@ var opcodeTable = [...]opInfo{ + hasSideEffects: true, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB ++ {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB + }, + }, + }, +@@ -24421,11 +24421,11 @@ var opcodeTable = [...]opInfo{ + unsafePoint: true, + reg: regInfo{ + inputs: []inputInfo{ +- {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 +- {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB ++ {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -24438,11 +24438,11 @@ var opcodeTable = [...]opInfo{ + unsafePoint: true, + reg: regInfo{ + inputs: []inputInfo{ +- {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 +- {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB ++ {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -24454,11 +24454,11 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AAMANDDBW, + reg: regInfo{ + inputs: []inputInfo{ +- {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 +- {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB ++ {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -24470,11 +24470,11 @@ var opcodeTable = [...]opInfo{ + asm: loong64.AAMORDBW, + reg: regInfo{ + inputs: []inputInfo{ +- {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 +- {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB ++ {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -24487,11 +24487,11 @@ var opcodeTable = [...]opInfo{ + unsafePoint: true, + reg: regInfo{ + inputs: []inputInfo{ +- {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 +- {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB ++ {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -24504,11 +24504,11 @@ var opcodeTable = [...]opInfo{ + unsafePoint: true, + reg: regInfo{ + inputs: []inputInfo{ +- {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 +- {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB ++ {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -24522,10 +24522,10 @@ var opcodeTable = [...]opInfo{ + unsafePoint: true, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB ++ {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -24539,10 +24539,10 @@ var opcodeTable = [...]opInfo{ + unsafePoint: true, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB ++ {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -24555,12 +24555,12 @@ var opcodeTable = [...]opInfo{ + unsafePoint: true, + reg: regInfo{ + inputs: []inputInfo{ +- {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 +- {2, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 +- {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB ++ {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {2, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -24573,12 +24573,12 @@ var opcodeTable = [...]opInfo{ + unsafePoint: true, + reg: regInfo{ + inputs: []inputInfo{ +- {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 +- {2, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 +- {0, 4611686019500081148}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 SB ++ {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {2, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 4611686019501129724}, // SP R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 SB + }, + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -24589,7 +24589,7 @@ var opcodeTable = [...]opInfo{ + faultOnNilArg0: true, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -24598,7 +24598,7 @@ var opcodeTable = [...]opInfo{ + argLen: 1, + reg: regInfo{ + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -24607,7 +24607,7 @@ var opcodeTable = [...]opInfo{ + argLen: 1, + reg: regInfo{ + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -24627,7 +24627,7 @@ var opcodeTable = [...]opInfo{ + rematerializeable: true, + reg: regInfo{ + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -24637,7 +24637,7 @@ var opcodeTable = [...]opInfo{ + rematerializeable: true, + reg: regInfo{ + outputs: []outputInfo{ +- {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, +@@ -40189,16 +40189,16 @@ var registersLOONG64 = [...]Register{ + {17, loong64.REG_R18, 14, "R18"}, + {18, loong64.REG_R19, 15, "R19"}, + {19, loong64.REG_R20, 16, "R20"}, +- {20, loong64.REG_R21, -1, "R21"}, ++ {20, loong64.REG_R21, 17, "R21"}, + {21, loong64.REGG, -1, "g"}, +- {22, loong64.REG_R23, 17, "R23"}, +- {23, loong64.REG_R24, 18, "R24"}, +- {24, loong64.REG_R25, 19, "R25"}, +- {25, loong64.REG_R26, 20, "R26"}, +- {26, loong64.REG_R27, 21, "R27"}, +- {27, loong64.REG_R28, 22, "R28"}, +- {28, loong64.REG_R29, 23, "R29"}, +- {29, loong64.REG_R31, 24, "R31"}, ++ {22, loong64.REG_R23, 18, "R23"}, ++ {23, loong64.REG_R24, 19, "R24"}, ++ {24, loong64.REG_R25, 20, "R25"}, ++ {25, loong64.REG_R26, 21, "R26"}, ++ {26, loong64.REG_R27, 22, "R27"}, ++ {27, loong64.REG_R28, 23, "R28"}, ++ {28, loong64.REG_R29, 24, "R29"}, ++ {29, loong64.REG_R31, 25, "R31"}, + {30, loong64.REG_F0, -1, "F0"}, + {31, loong64.REG_F1, -1, "F1"}, + {32, loong64.REG_F2, -1, "F2"}, +@@ -40235,7 +40235,7 @@ var registersLOONG64 = [...]Register{ + } + var paramIntRegLOONG64 = []int8{3, 4, 5, 6, 7, 8, 9, 10} + var paramFloatRegLOONG64 = []int8{30, 31, 32, 33, 34, 35, 36, 37} +-var gpRegMaskLOONG64 = regMask(1070596088) ++var gpRegMaskLOONG64 = regMask(1071644664) + var fpRegMaskLOONG64 = regMask(4611686017353646080) + var specialRegMaskLOONG64 = regMask(0) + var framepointerRegLOONG64 = int8(-1) +diff --git a/src/cmd/internal/obj/loong64/a.out.go b/src/cmd/internal/obj/loong64/a.out.go +index 3ed15fc7e7..8df48a1e01 100644 +--- a/src/cmd/internal/obj/loong64/a.out.go ++++ b/src/cmd/internal/obj/loong64/a.out.go +@@ -157,14 +157,14 @@ const ( + REGZERO = REG_R0 // set to zero + REGLINK = REG_R1 + REGSP = REG_R3 +- REGRET = REG_R19 ++ REGRET = REG_R20 // not use + REGARG = -1 // -1 disables passing the first argument in register +- REGRT1 = REG_R19 // reserved for runtime, duffzero and duffcopy +- REGRT2 = REG_R20 // reserved for runtime, duffcopy ++ REGRT1 = REG_R20 // reserved for runtime, duffzero and duffcopy ++ REGRT2 = REG_R21 // reserved for runtime, duffcopy + REGCTXT = REG_R29 // context for closures + REGG = REG_R22 // G in loong64 + REGTMP = REG_R30 // used by the assembler +- FREGRET = REG_F0 ++ FREGRET = REG_F0 // not use + ) + + var LOONG64DWARFRegisters = map[int16]int16{} +diff --git a/src/runtime/duff_loong64.s b/src/runtime/duff_loong64.s +index 63fa3bcca1..df8b653965 100644 +--- a/src/runtime/duff_loong64.s ++++ b/src/runtime/duff_loong64.s +@@ -5,903 +5,903 @@ + #include "textflag.h" + + TEXT runtime·duffzero(SB), NOSPLIT|NOFRAME, $0-0 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 +- MOVV R0, (R19) +- ADDV $8, R19 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 ++ MOVV R0, (R20) ++ ADDV $8, R20 + RET + + TEXT runtime·duffcopy(SB), NOSPLIT|NOFRAME, $0-0 +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + +- MOVV (R19), R30 +- ADDV $8, R19 +- MOVV R30, (R20) ++ MOVV (R20), R30 + ADDV $8, R20 ++ MOVV R30, (R21) ++ ADDV $8, R21 + + RET +diff --git a/src/runtime/mkduff.go b/src/runtime/mkduff.go +index e8d4fcc93e..77674254d4 100644 +--- a/src/runtime/mkduff.go ++++ b/src/runtime/mkduff.go +@@ -183,8 +183,8 @@ func zeroLOONG64(w io.Writer) { + // On return, R19 points to the last zeroed dword. + fmt.Fprintln(w, "TEXT runtime·duffzero(SB), NOSPLIT|NOFRAME, $0-0") + for i := 0; i < 128; i++ { +- fmt.Fprintln(w, "\tMOVV\tR0, (R19)") +- fmt.Fprintln(w, "\tADDV\t$8, R19") ++ fmt.Fprintln(w, "\tMOVV\tR0, (R20)") ++ fmt.Fprintln(w, "\tADDV\t$8, R20") + } + fmt.Fprintln(w, "\tRET") + } +@@ -192,10 +192,10 @@ func zeroLOONG64(w io.Writer) { + func copyLOONG64(w io.Writer) { + fmt.Fprintln(w, "TEXT runtime·duffcopy(SB), NOSPLIT|NOFRAME, $0-0") + for i := 0; i < 128; i++ { +- fmt.Fprintln(w, "\tMOVV\t(R19), R30") +- fmt.Fprintln(w, "\tADDV\t$8, R19") +- fmt.Fprintln(w, "\tMOVV\tR30, (R20)") ++ fmt.Fprintln(w, "\tMOVV\t(R20), R30") + fmt.Fprintln(w, "\tADDV\t$8, R20") ++ fmt.Fprintln(w, "\tMOVV\tR30, (R21)") ++ fmt.Fprintln(w, "\tADDV\t$8, R21") + fmt.Fprintln(w) + } + fmt.Fprintln(w, "\tRET") +-- +2.20.1 + diff --git a/loongarch64/0022-cmd-compile-add-ABI-register-definations-for-loong64.patch b/loongarch64/0022-cmd-compile-add-ABI-register-definations-for-loong64.patch new file mode 100644 index 0000000000000000000000000000000000000000..333feb90ee7349a5bfeb592df0481c03f14e5882 --- /dev/null +++ b/loongarch64/0022-cmd-compile-add-ABI-register-definations-for-loong64.patch @@ -0,0 +1,77 @@ +From 96ca1b28d6a95d8f33a5e4b46d22fc7cb6cd46c6 Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Tue, 15 Aug 2023 17:11:19 +0800 +Subject: [PATCH 22/51] cmd/compile: add ABI register definations for loong64 + +Updates #40724 + +Co-authored-by: Xiaolin Zhao +Change-Id: Idc30393487077e5c2bdffab447e3d8c33d4c8925 +--- + src/cmd/compile/abi-internal.md | 50 +++++++++++++++++++++++++++++++++ + 1 file changed, 50 insertions(+) + +diff --git a/src/cmd/compile/abi-internal.md b/src/cmd/compile/abi-internal.md +index 14464ed904..db5197fb72 100644 +--- a/src/cmd/compile/abi-internal.md ++++ b/src/cmd/compile/abi-internal.md +@@ -633,6 +633,56 @@ modifying or saving the FPCR. + Functions are allowed to modify it between calls (as long as they + restore it), but as of this writing Go code never does. + ++### loong64 architecture ++ ++The loong64 architecture uses R4 – R19 for integer arguments and integer results. ++ ++It uses F0 – F15 for floating-point arguments and results. ++ ++Registers R20 - R21, R23 – R28, R30, F16 – F31 are permanent scratch registers. ++ ++Register R2 is reserved and never used. ++ ++Register R20, R21 is Used by runtime.duffcopy, runtime.duffzero. ++ ++Special-purpose registers used within Go generated code and Go assembly code ++are as follows: ++ ++| Register | Call meaning | Return meaning | Body meaning | ++| --- | --- | --- | --- | ++| R0 | Zero value | Same | Same | ++| R1 | Link register | Link register | Scratch | ++| R3 | Stack pointer | Same | Same | ++| R20,R21 | Scratch | Scratch | Used by duffcopy, duffzero | ++| R22 | Current goroutine | Same | Same | ++| R29 | Closure context pointer | Same | Same | ++| R30 | used by the assembler | Same | Same | ++ ++*Rationale*: These register meanings are compatible with Go’s stack-based ++calling convention. ++ ++#### Stack layout ++ ++The stack pointer, R3, grows down and is aligned to 8 bytes. ++ ++A function's stack frame, after the frame is created, is laid out as ++follows: ++ ++ +------------------------------+ ++ | ... locals ... | ++ | ... outgoing arguments ... | ++ | return PC | ← R3 points to ++ +------------------------------+ ↓ lower addresses ++ ++This stack layout is used by both register-based (ABIInternal) and ++stack-based (ABI0) calling conventions. ++ ++The "return PC" is loaded to the link register, R1, as part of the ++loong64 `JAL` operation. ++ ++#### Flags ++All bits in CSR are system flags and are not modified by Go. ++ + ### ppc64 architecture + + The ppc64 architecture uses R3 – R10 and R14 – R17 for integer arguments +-- +2.20.1 + diff --git a/loongarch64/0023-cmd-compile-cmd-internal-runtime-change-registers-on.patch b/loongarch64/0023-cmd-compile-cmd-internal-runtime-change-registers-on.patch new file mode 100644 index 0000000000000000000000000000000000000000..efe413ea878e1787aadf0369425a6cacb11d371e --- /dev/null +++ b/loongarch64/0023-cmd-compile-cmd-internal-runtime-change-registers-on.patch @@ -0,0 +1,405 @@ +From 1a0cfe2573c5ac0eb77205cea3880620dfe3350f Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Tue, 15 Aug 2023 19:23:51 +0800 +Subject: [PATCH 23/51] cmd/compile,cmd/internal,runtime: change registers on + loong64 to avoid regABI arguments + +Update #40724 + +Co-authored-by: Xiaolin Zhao +Change-Id: I2be59a7300aa4f0ee9af509e2cc7201a968f7228 +--- + .../compile/internal/ssa/_gen/LOONG64Ops.go | 8 +- + src/cmd/compile/internal/ssa/opGen.go | 12 +-- + src/cmd/internal/obj/loong64/obj.go | 68 ++++++++--------- + src/runtime/asm_loong64.s | 74 +++++++++---------- + 4 files changed, 81 insertions(+), 81 deletions(-) + +diff --git a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go +index 9950619baf..0d0f475a5b 100644 +--- a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go ++++ b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go +@@ -130,10 +130,10 @@ func init() { + gpspsbg = gpspg | buildReg("SB") + fp = buildReg("F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31") + callerSave = gp | fp | buildReg("g") // runtime.setg (and anything calling it) may clobber g +- r1 = buildReg("R19") +- r2 = buildReg("R18") +- r3 = buildReg("R17") +- r4 = buildReg("R4") ++ r1 = buildReg("R20") ++ r2 = buildReg("R21") ++ r3 = buildReg("R23") ++ r4 = buildReg("R24") + ) + // Common regInfo + var ( +diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go +index 2c17801ea4..6643aef21a 100644 +--- a/src/cmd/compile/internal/ssa/opGen.go ++++ b/src/cmd/compile/internal/ssa/opGen.go +@@ -24660,8 +24660,8 @@ var opcodeTable = [...]opInfo{ + call: true, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 65536}, // R17 +- {1, 8}, // R4 ++ {0, 4194304}, // R23 ++ {1, 8388608}, // R24 + }, + }, + }, +@@ -24672,8 +24672,8 @@ var opcodeTable = [...]opInfo{ + call: true, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 131072}, // R18 +- {1, 65536}, // R17 ++ {0, 1048576}, // R21 ++ {1, 4194304}, // R23 + }, + }, + }, +@@ -24684,8 +24684,8 @@ var opcodeTable = [...]opInfo{ + call: true, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 262144}, // R19 +- {1, 131072}, // R18 ++ {0, 524288}, // R20 ++ {1, 1048576}, // R21 + }, + }, + }, +diff --git a/src/cmd/internal/obj/loong64/obj.go b/src/cmd/internal/obj/loong64/obj.go +index 38ab66b819..b0f5ac3087 100644 +--- a/src/cmd/internal/obj/loong64/obj.go ++++ b/src/cmd/internal/obj/loong64/obj.go +@@ -402,13 +402,13 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { + if c.cursym.Func().Text.From.Sym.Wrapper() && c.cursym.Func().Text.Mark&LEAF == 0 { + // if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame + // +- // MOV g_panic(g), R1 +- // BEQ R1, end +- // MOV panic_argp(R1), R2 +- // ADD $(autosize+FIXED_FRAME), R29, R3 +- // BNE R2, R3, end +- // ADD $FIXED_FRAME, R29, R2 +- // MOV R2, panic_argp(R1) ++ // MOV g_panic(g), R20 ++ // BEQ R20, end ++ // MOV panic_argp(R20), R24 ++ // ADD $(autosize+FIXED_FRAME), R3, R30 ++ // BNE R24, R30, end ++ // ADD $FIXED_FRAME, R3, R24 ++ // MOV R24, panic_argp(R20) + // end: + // NOP + // +@@ -425,12 +425,12 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { + q.From.Reg = REGG + q.From.Offset = 4 * int64(c.ctxt.Arch.PtrSize) // G.panic + q.To.Type = obj.TYPE_REG +- q.To.Reg = REG_R19 ++ q.To.Reg = REG_R20 + + q = obj.Appendp(q, newprog) + q.As = ABEQ + q.From.Type = obj.TYPE_REG +- q.From.Reg = REG_R19 ++ q.From.Reg = REG_R20 + q.To.Type = obj.TYPE_BRANCH + q.Mark |= BRANCH + p1 = q +@@ -438,10 +438,10 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { + q = obj.Appendp(q, newprog) + q.As = mov + q.From.Type = obj.TYPE_MEM +- q.From.Reg = REG_R19 ++ q.From.Reg = REG_R20 + q.From.Offset = 0 // Panic.argp + q.To.Type = obj.TYPE_REG +- q.To.Reg = REG_R4 ++ q.To.Reg = REG_R24 + + q = obj.Appendp(q, newprog) + q.As = add +@@ -449,13 +449,13 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { + q.From.Offset = int64(autosize) + ctxt.Arch.FixedFrameSize + q.Reg = REGSP + q.To.Type = obj.TYPE_REG +- q.To.Reg = REG_R5 ++ q.To.Reg = REG_R30 + + q = obj.Appendp(q, newprog) + q.As = ABNE + q.From.Type = obj.TYPE_REG +- q.From.Reg = REG_R4 +- q.Reg = REG_R5 ++ q.From.Reg = REG_R24 ++ q.Reg = REG_R30 + q.To.Type = obj.TYPE_BRANCH + q.Mark |= BRANCH + p2 = q +@@ -466,14 +466,14 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { + q.From.Offset = ctxt.Arch.FixedFrameSize + q.Reg = REGSP + q.To.Type = obj.TYPE_REG +- q.To.Reg = REG_R4 ++ q.To.Reg = REG_R24 + + q = obj.Appendp(q, newprog) + q.As = mov + q.From.Type = obj.TYPE_REG +- q.From.Reg = REG_R4 ++ q.From.Reg = REG_R24 + q.To.Type = obj.TYPE_MEM +- q.To.Reg = REG_R19 ++ q.To.Reg = REG_R20 + q.To.Offset = 0 // Panic.argp + + q = obj.Appendp(q, newprog) +@@ -696,7 +696,7 @@ func (c *ctxt0) stacksplit(p *obj.Prog, framesize int32) *obj.Prog { + // Jump back to here after morestack returns. + startPred := p + +- // MOV g_stackguard(g), R19 ++ // MOV g_stackguard(g), R20 + p = obj.Appendp(p, c.newprog) + + p.As = mov +@@ -707,7 +707,7 @@ func (c *ctxt0) stacksplit(p *obj.Prog, framesize int32) *obj.Prog { + p.From.Offset = 3 * int64(c.ctxt.Arch.PtrSize) // G.stackguard1 + } + p.To.Type = obj.TYPE_REG +- p.To.Reg = REG_R19 ++ p.To.Reg = REG_R20 + + // Mark the stack bound check and morestack call async nonpreemptible. + // If we get preempted here, when resumed the preemption request is +@@ -718,15 +718,15 @@ func (c *ctxt0) stacksplit(p *obj.Prog, framesize int32) *obj.Prog { + var q *obj.Prog + if framesize <= abi.StackSmall { + // small stack: SP < stackguard +- // AGTU SP, stackguard, R19 ++ // AGTU SP, stackguard, R20 + p = obj.Appendp(p, c.newprog) + + p.As = ASGTU + p.From.Type = obj.TYPE_REG + p.From.Reg = REGSP +- p.Reg = REG_R19 ++ p.Reg = REG_R20 + p.To.Type = obj.TYPE_REG +- p.To.Reg = REG_R19 ++ p.To.Reg = REG_R20 + } else { + // large stack: SP-framesize < stackguard-StackSmall + offset := int64(framesize) - abi.StackSmall +@@ -738,8 +738,8 @@ func (c *ctxt0) stacksplit(p *obj.Prog, framesize int32) *obj.Prog { + // stack guard to incorrectly succeed. We explicitly + // guard against underflow. + // +- // SGTU $(framesize-StackSmall), SP, R4 +- // BNE R4, label-of-call-to-morestack ++ // SGTU $(framesize-StackSmall), SP, R24 ++ // BNE R24, label-of-call-to-morestack + + p = obj.Appendp(p, c.newprog) + p.As = ASGTU +@@ -747,13 +747,13 @@ func (c *ctxt0) stacksplit(p *obj.Prog, framesize int32) *obj.Prog { + p.From.Offset = offset + p.Reg = REGSP + p.To.Type = obj.TYPE_REG +- p.To.Reg = REG_R4 ++ p.To.Reg = REG_R24 + + p = obj.Appendp(p, c.newprog) + q = p + p.As = ABNE + p.From.Type = obj.TYPE_REG +- p.From.Reg = REG_R4 ++ p.From.Reg = REG_R24 + p.To.Type = obj.TYPE_BRANCH + p.Mark |= BRANCH + } +@@ -765,35 +765,35 @@ func (c *ctxt0) stacksplit(p *obj.Prog, framesize int32) *obj.Prog { + p.From.Offset = -offset + p.Reg = REGSP + p.To.Type = obj.TYPE_REG +- p.To.Reg = REG_R4 ++ p.To.Reg = REG_R24 + + p = obj.Appendp(p, c.newprog) + p.As = ASGTU + p.From.Type = obj.TYPE_REG +- p.From.Reg = REG_R4 +- p.Reg = REG_R19 ++ p.From.Reg = REG_R24 ++ p.Reg = REG_R20 + p.To.Type = obj.TYPE_REG +- p.To.Reg = REG_R19 ++ p.To.Reg = REG_R20 + } + +- // q1: BNE R19, done ++ // q1: BNE R20, done + p = obj.Appendp(p, c.newprog) + q1 := p + + p.As = ABNE + p.From.Type = obj.TYPE_REG +- p.From.Reg = REG_R19 ++ p.From.Reg = REG_R20 + p.To.Type = obj.TYPE_BRANCH + p.Mark |= BRANCH + +- // MOV LINK, R5 ++ // MOV LINK, R30 + p = obj.Appendp(p, c.newprog) + + p.As = mov + p.From.Type = obj.TYPE_REG + p.From.Reg = REGLINK + p.To.Type = obj.TYPE_REG +- p.To.Reg = REG_R5 ++ p.To.Reg = REG_R30 + if q != nil { + q.To.SetTarget(p) + p.Mark |= LABEL +diff --git a/src/runtime/asm_loong64.s b/src/runtime/asm_loong64.s +index 78a1a4d358..23cbd09947 100644 +--- a/src/runtime/asm_loong64.s ++++ b/src/runtime/asm_loong64.s +@@ -214,7 +214,7 @@ noswitch: + + // Called during function prolog when more stack is needed. + // Caller has already loaded: +-// loong64: R5: LR ++// loong64: R30: LR + // + // The traceback routines see morestack on a g0 as being + // the top of a stack (for example, morestack calling newstack +@@ -238,12 +238,12 @@ TEXT runtime·morestack(SB),NOSPLIT|NOFRAME,$0-0 + // Set g->sched to context in f. + MOVV R3, (g_sched+gobuf_sp)(g) + MOVV R1, (g_sched+gobuf_pc)(g) +- MOVV R5, (g_sched+gobuf_lr)(g) ++ MOVV R30, (g_sched+gobuf_lr)(g) + MOVV REGCTXT, (g_sched+gobuf_ctxt)(g) + + // Called from f. + // Set m->morebuf to f's caller. +- MOVV R5, (m_morebuf+gobuf_pc)(R7) // f's caller's PC ++ MOVV R30, (m_morebuf+gobuf_pc)(R7) // f's caller's PC + MOVV R3, (m_morebuf+gobuf_sp)(R7) // f's caller's SP + MOVV g, (m_morebuf+gobuf_g)(R7) + +@@ -786,70 +786,70 @@ TEXT runtime·gcWriteBarrier8(SB),NOSPLIT,$0 + // then tail call to the corresponding runtime handler. + // The tail call makes these stubs disappear in backtraces. + TEXT runtime·panicIndex(SB),NOSPLIT,$0-16 +- MOVV R19, x+0(FP) +- MOVV R18, y+8(FP) ++ MOVV R20, x+0(FP) ++ MOVV R21, y+8(FP) + JMP runtime·goPanicIndex(SB) + TEXT runtime·panicIndexU(SB),NOSPLIT,$0-16 +- MOVV R19, x+0(FP) +- MOVV R18, y+8(FP) ++ MOVV R20, x+0(FP) ++ MOVV R21, y+8(FP) + JMP runtime·goPanicIndexU(SB) + TEXT runtime·panicSliceAlen(SB),NOSPLIT,$0-16 +- MOVV R18, x+0(FP) +- MOVV R17, y+8(FP) ++ MOVV R21, x+0(FP) ++ MOVV R23, y+8(FP) + JMP runtime·goPanicSliceAlen(SB) + TEXT runtime·panicSliceAlenU(SB),NOSPLIT,$0-16 +- MOVV R18, x+0(FP) +- MOVV R17, y+8(FP) ++ MOVV R21, x+0(FP) ++ MOVV R23, y+8(FP) + JMP runtime·goPanicSliceAlenU(SB) + TEXT runtime·panicSliceAcap(SB),NOSPLIT,$0-16 +- MOVV R18, x+0(FP) +- MOVV R17, y+8(FP) ++ MOVV R21, x+0(FP) ++ MOVV R23, y+8(FP) + JMP runtime·goPanicSliceAcap(SB) + TEXT runtime·panicSliceAcapU(SB),NOSPLIT,$0-16 +- MOVV R18, x+0(FP) +- MOVV R17, y+8(FP) ++ MOVV R21, x+0(FP) ++ MOVV R23, y+8(FP) + JMP runtime·goPanicSliceAcapU(SB) + TEXT runtime·panicSliceB(SB),NOSPLIT,$0-16 +- MOVV R19, x+0(FP) +- MOVV R18, y+8(FP) ++ MOVV R20, x+0(FP) ++ MOVV R21, y+8(FP) + JMP runtime·goPanicSliceB(SB) + TEXT runtime·panicSliceBU(SB),NOSPLIT,$0-16 +- MOVV R19, x+0(FP) +- MOVV R18, y+8(FP) ++ MOVV R20, x+0(FP) ++ MOVV R21, y+8(FP) + JMP runtime·goPanicSliceBU(SB) + TEXT runtime·panicSlice3Alen(SB),NOSPLIT,$0-16 +- MOVV R17, x+0(FP) +- MOVV R4, y+8(FP) ++ MOVV R23, x+0(FP) ++ MOVV R24, y+8(FP) + JMP runtime·goPanicSlice3Alen(SB) + TEXT runtime·panicSlice3AlenU(SB),NOSPLIT,$0-16 +- MOVV R17, x+0(FP) +- MOVV R4, y+8(FP) ++ MOVV R23, x+0(FP) ++ MOVV R24, y+8(FP) + JMP runtime·goPanicSlice3AlenU(SB) + TEXT runtime·panicSlice3Acap(SB),NOSPLIT,$0-16 +- MOVV R17, x+0(FP) +- MOVV R4, y+8(FP) ++ MOVV R23, x+0(FP) ++ MOVV R24, y+8(FP) + JMP runtime·goPanicSlice3Acap(SB) + TEXT runtime·panicSlice3AcapU(SB),NOSPLIT,$0-16 +- MOVV R17, x+0(FP) +- MOVV R4, y+8(FP) ++ MOVV R23, x+0(FP) ++ MOVV R24, y+8(FP) + JMP runtime·goPanicSlice3AcapU(SB) + TEXT runtime·panicSlice3B(SB),NOSPLIT,$0-16 +- MOVV R18, x+0(FP) +- MOVV R17, y+8(FP) ++ MOVV R21, x+0(FP) ++ MOVV R23, y+8(FP) + JMP runtime·goPanicSlice3B(SB) + TEXT runtime·panicSlice3BU(SB),NOSPLIT,$0-16 +- MOVV R18, x+0(FP) +- MOVV R17, y+8(FP) ++ MOVV R21, x+0(FP) ++ MOVV R23, y+8(FP) + JMP runtime·goPanicSlice3BU(SB) + TEXT runtime·panicSlice3C(SB),NOSPLIT,$0-16 +- MOVV R19, x+0(FP) +- MOVV R18, y+8(FP) ++ MOVV R20, x+0(FP) ++ MOVV R21, y+8(FP) + JMP runtime·goPanicSlice3C(SB) + TEXT runtime·panicSlice3CU(SB),NOSPLIT,$0-16 +- MOVV R19, x+0(FP) +- MOVV R18, y+8(FP) ++ MOVV R20, x+0(FP) ++ MOVV R21, y+8(FP) + JMP runtime·goPanicSlice3CU(SB) + TEXT runtime·panicSliceConvert(SB),NOSPLIT,$0-16 +- MOVV R17, x+0(FP) +- MOVV R4, y+8(FP) ++ MOVV R23, x+0(FP) ++ MOVV R24, y+8(FP) + JMP runtime·goPanicSliceConvert(SB) +-- +2.20.1 + diff --git a/loongarch64/0024-internal-abi-define-loong64-regABI-constants.patch b/loongarch64/0024-internal-abi-define-loong64-regABI-constants.patch new file mode 100644 index 0000000000000000000000000000000000000000..a4bc78cceb29e0b485af61494c5fa542141b998a --- /dev/null +++ b/loongarch64/0024-internal-abi-define-loong64-regABI-constants.patch @@ -0,0 +1,42 @@ +From 97ebe3d5e70d144a940fa1264e7a6762ebcd2ad0 Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Tue, 15 Aug 2023 19:38:33 +0800 +Subject: [PATCH 24/51] internal/abi: define loong64 regABI constants + +Update #40724 + +Co-authored-by: Xiaolin Zhao +Change-Id: Id580d9e22a562adee2ae02a467ac38a54949e737 +--- + src/internal/abi/abi_loong64.go | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + create mode 100644 src/internal/abi/abi_loong64.go + +diff --git a/src/internal/abi/abi_loong64.go b/src/internal/abi/abi_loong64.go +new file mode 100644 +index 0000000000..c2306ae8d8 +--- /dev/null ++++ b/src/internal/abi/abi_loong64.go +@@ -0,0 +1,19 @@ ++// Copyright 2023 The Go Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style ++// license that can be found in the LICENSE file. ++ ++//go:build goexperiment.regabiargs ++ ++package abi ++ ++const ( ++ // See abi_generic.go. ++ ++ // R4 - R19 ++ IntArgRegs = 16 ++ ++ // F0 - F15 ++ FloatArgRegs = 16 ++ ++ EffectiveFloatRegSize = 8 ++) +-- +2.20.1 + diff --git a/loongarch64/0025-cmd-compile-internal-add-register-info-for-loong64-r.patch b/loongarch64/0025-cmd-compile-internal-add-register-info-for-loong64-r.patch new file mode 100644 index 0000000000000000000000000000000000000000..e933da65b82895eab865d86294f4fc733f87b0e5 --- /dev/null +++ b/loongarch64/0025-cmd-compile-internal-add-register-info-for-loong64-r.patch @@ -0,0 +1,76 @@ +From da81ad6362ca3fa6c87a43d3dbf25b210e65d67f Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Tue, 15 Aug 2023 19:54:51 +0800 +Subject: [PATCH 25/51] cmd/compile/internal: add register info for loong64 + regABI + +Update #40724 + +Co-authored-by: Xiaolin Zhao +Change-Id: I4b40d0c17c479392ceaef65a8fd40a9117b87b4f +--- + src/cmd/compile/internal/loong64/ssa.go | 2 ++ + src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go | 4 ++-- + src/cmd/compile/internal/ssa/config.go | 2 ++ + src/cmd/compile/internal/ssa/opGen.go | 4 ++-- + 4 files changed, 8 insertions(+), 4 deletions(-) + +diff --git a/src/cmd/compile/internal/loong64/ssa.go b/src/cmd/compile/internal/loong64/ssa.go +index 199fd4ce33..f348f396b8 100644 +--- a/src/cmd/compile/internal/loong64/ssa.go ++++ b/src/cmd/compile/internal/loong64/ssa.go +@@ -144,6 +144,8 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) { + p.From.Type = obj.TYPE_REG + p.From.Reg = r + ssagen.AddrAuto(&p.To, v) ++ case ssa.OpArgIntReg, ssa.OpArgFloatReg: ++ ssagen.CheckArgReg(v) + case ssa.OpLOONG64ADDV, + ssa.OpLOONG64SUBV, + ssa.OpLOONG64AND, +diff --git a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go +index 0d0f475a5b..8e3f3ce720 100644 +--- a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go ++++ b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go +@@ -466,8 +466,8 @@ func init() { + blocks: blocks, + regnames: regNamesLOONG64, + // TODO: support register ABI on loong64 +- ParamIntRegNames: "R4 R5 R6 R7 R8 R9 R10 R11", +- ParamFloatRegNames: "F0 F1 F2 F3 F4 F5 F6 F7", ++ ParamIntRegNames: "R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19", ++ ParamFloatRegNames: "F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15", + gpregmask: gp, + fpregmask: fp, + framepointerreg: -1, // not used +diff --git a/src/cmd/compile/internal/ssa/config.go b/src/cmd/compile/internal/ssa/config.go +index 43f9f0affc..31a6ee1af8 100644 +--- a/src/cmd/compile/internal/ssa/config.go ++++ b/src/cmd/compile/internal/ssa/config.go +@@ -296,6 +296,8 @@ func NewConfig(arch string, types Types, ctxt *obj.Link, optimize, softfloat boo + c.registers = registersLOONG64[:] + c.gpRegMask = gpRegMaskLOONG64 + c.fpRegMask = fpRegMaskLOONG64 ++ // c.intParamRegs = paramIntRegLOONG64 ++ // c.floatParamRegs = paramFloatRegLOONG64 + c.FPReg = framepointerRegLOONG64 + c.LinkReg = linkRegLOONG64 + c.hasGReg = true +diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go +index 6643aef21a..482046f016 100644 +--- a/src/cmd/compile/internal/ssa/opGen.go ++++ b/src/cmd/compile/internal/ssa/opGen.go +@@ -40233,8 +40233,8 @@ var registersLOONG64 = [...]Register{ + {61, loong64.REG_F31, -1, "F31"}, + {62, 0, -1, "SB"}, + } +-var paramIntRegLOONG64 = []int8{3, 4, 5, 6, 7, 8, 9, 10} +-var paramFloatRegLOONG64 = []int8{30, 31, 32, 33, 34, 35, 36, 37} ++var paramIntRegLOONG64 = []int8{3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18} ++var paramFloatRegLOONG64 = []int8{30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45} + var gpRegMaskLOONG64 = regMask(1071644664) + var fpRegMaskLOONG64 = regMask(4611686017353646080) + var specialRegMaskLOONG64 = regMask(0) +-- +2.20.1 + diff --git a/loongarch64/0026-cmd-compile-internal-add-spill-support-for-loong64-r.patch b/loongarch64/0026-cmd-compile-internal-add-spill-support-for-loong64-r.patch new file mode 100644 index 0000000000000000000000000000000000000000..0a3ed4cd595f868786c029a21788974f110de8f2 --- /dev/null +++ b/loongarch64/0026-cmd-compile-internal-add-spill-support-for-loong64-r.patch @@ -0,0 +1,81 @@ +From 301f2835624e687f1a056ddb630d368b13c10214 Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Tue, 15 Aug 2023 20:10:33 +0800 +Subject: [PATCH 26/51] cmd/compile/internal: add spill support for loong64 + regABI + +Update #40724 + +Co-authored-by: Xiaolin Zhao +Change-Id: I4a194177562dd1f15add5c32696bd69b027d88d7 +--- + src/cmd/compile/internal/loong64/galign.go | 2 ++ + src/cmd/compile/internal/loong64/ssa.go | 30 ++++++++++++++++++++++ + 2 files changed, 32 insertions(+) + +diff --git a/src/cmd/compile/internal/loong64/galign.go b/src/cmd/compile/internal/loong64/galign.go +index 99ab7bdfb5..a613165054 100644 +--- a/src/cmd/compile/internal/loong64/galign.go ++++ b/src/cmd/compile/internal/loong64/galign.go +@@ -20,4 +20,6 @@ func Init(arch *ssagen.ArchInfo) { + arch.SSAMarkMoves = func(s *ssagen.State, b *ssa.Block) {} + arch.SSAGenValue = ssaGenValue + arch.SSAGenBlock = ssaGenBlock ++ arch.LoadRegResult = loadRegResult ++ arch.SpillArgReg = spillArgReg + } +diff --git a/src/cmd/compile/internal/loong64/ssa.go b/src/cmd/compile/internal/loong64/ssa.go +index f348f396b8..278f30649f 100644 +--- a/src/cmd/compile/internal/loong64/ssa.go ++++ b/src/cmd/compile/internal/loong64/ssa.go +@@ -10,6 +10,7 @@ import ( + "cmd/compile/internal/base" + "cmd/compile/internal/ir" + "cmd/compile/internal/logopt" ++ "cmd/compile/internal/objw" + "cmd/compile/internal/ssa" + "cmd/compile/internal/ssagen" + "cmd/compile/internal/types" +@@ -145,6 +146,16 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) { + p.From.Reg = r + ssagen.AddrAuto(&p.To, v) + case ssa.OpArgIntReg, ssa.OpArgFloatReg: ++ // The assembler needs to wrap the entry safepoint/stack growth code with spill/unspill ++ // The loop only runs once. ++ for _, a := range v.Block.Func.RegArgs { ++ // Pass the spill/unspill information along to the assembler, offset by size of ++ // the saved LR slot. ++ addr := ssagen.SpillSlotAddr(a, loong64.REGSP, base.Ctxt.Arch.FixedFrameSize) ++ s.FuncInfo().AddSpill( ++ obj.RegSpill{Reg: a.Reg, Addr: addr, Unspill: loadByType(a.Type, a.Reg), Spill: storeByType(a.Type, a.Reg)}) ++ } ++ v.Block.Func.RegArgs = nil + ssagen.CheckArgReg(v) + case ssa.OpLOONG64ADDV, + ssa.OpLOONG64SUBV, +@@ -763,3 +774,22 @@ func ssaGenBlock(s *ssagen.State, b, next *ssa.Block) { + b.Fatalf("branch not implemented: %s", b.LongString()) + } + } ++ ++func loadRegResult(s *ssagen.State, f *ssa.Func, t *types.Type, reg int16, n *ir.Name, off int64) *obj.Prog { ++ p := s.Prog(loadByType(t, reg)) ++ p.From.Type = obj.TYPE_MEM ++ p.From.Name = obj.NAME_AUTO ++ p.From.Sym = n.Linksym() ++ p.From.Offset = n.FrameOffset() + off ++ p.To.Type = obj.TYPE_REG ++ p.To.Reg = reg ++ return p ++} ++ ++func spillArgReg(pp *objw.Progs, p *obj.Prog, f *ssa.Func, t *types.Type, reg int16, n *ir.Name, off int64) *obj.Prog { ++ p = pp.Append(p, storeByType(t, reg), obj.TYPE_REG, reg, 0, obj.TYPE_MEM, 0, n.FrameOffset()+off) ++ p.To.Name = obj.NAME_PARAM ++ p.To.Sym = n.Linksym() ++ p.Pos = p.Pos.WithNotStmt() ++ return p ++} +-- +2.20.1 + diff --git a/loongarch64/0027-cmd-compile-update-loong64-CALL-ops.patch b/loongarch64/0027-cmd-compile-update-loong64-CALL-ops.patch new file mode 100644 index 0000000000000000000000000000000000000000..02c6ed863eff81a4c3f20bee64583ffae25583fb --- /dev/null +++ b/loongarch64/0027-cmd-compile-update-loong64-CALL-ops.patch @@ -0,0 +1,78 @@ +From d6a8d621907fff3c6161c5ce48746920edf68fe9 Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Tue, 15 Aug 2023 20:23:46 +0800 +Subject: [PATCH 27/51] cmd/compile: update loong64 CALL* ops + +allow the loong64 CALL* ops to take variable number of args + +Update #40724 + +Co-authored-by: Xiaolin Zhao +Change-Id: I117c6b48e0fbbe3ed8fd4c133895178c2cf288b1 +--- + src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go | 8 ++++---- + src/cmd/compile/internal/ssa/opGen.go | 8 ++++---- + 2 files changed, 8 insertions(+), 8 deletions(-) + +diff --git a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go +index 8e3f3ce720..9a83965493 100644 +--- a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go ++++ b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go +@@ -273,10 +273,10 @@ func init() { + {name: "MOVDF", argLength: 1, reg: fp11, asm: "MOVDF"}, // float64 -> float32 + + // function calls +- {name: "CALLstatic", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call static function aux.(*obj.LSym). arg0=mem, auxint=argsize, returns mem +- {name: "CALLtail", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true, tailCall: true}, // tail call static function aux.(*obj.LSym). arg0=mem, auxint=argsize, returns mem +- {name: "CALLclosure", argLength: 3, reg: regInfo{inputs: []regMask{gpsp, buildReg("R29"), 0}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call function via closure. arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem +- {name: "CALLinter", argLength: 2, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call fn by pointer. arg0=codeptr, arg1=mem, auxint=argsize, returns mem ++ {name: "CALLstatic", argLength: -1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call static function aux.(*obj.LSym). last arg=mem, auxint=argsize, returns mem ++ {name: "CALLtail", argLength: -1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true, tailCall: true}, // tail call static function aux.(*obj.LSym). last arg=mem, auxint=argsize, returns mem ++ {name: "CALLclosure", argLength: -1, reg: regInfo{inputs: []regMask{gpsp, buildReg("R29"), 0}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call function via closure. arg0=codeptr, arg1=closure, last arg=mem, auxint=argsize, returns mem ++ {name: "CALLinter", argLength: -1, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call fn by pointer. arg0=codeptr, last arg=mem, auxint=argsize, returns mem + + // duffzero + // arg0 = address of memory to zero +diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go +index 482046f016..290ad2682c 100644 +--- a/src/cmd/compile/internal/ssa/opGen.go ++++ b/src/cmd/compile/internal/ssa/opGen.go +@@ -24216,7 +24216,7 @@ var opcodeTable = [...]opInfo{ + { + name: "CALLstatic", + auxType: auxCallOff, +- argLen: 1, ++ argLen: -1, + clobberFlags: true, + call: true, + reg: regInfo{ +@@ -24226,7 +24226,7 @@ var opcodeTable = [...]opInfo{ + { + name: "CALLtail", + auxType: auxCallOff, +- argLen: 1, ++ argLen: -1, + clobberFlags: true, + call: true, + tailCall: true, +@@ -24237,7 +24237,7 @@ var opcodeTable = [...]opInfo{ + { + name: "CALLclosure", + auxType: auxCallOff, +- argLen: 3, ++ argLen: -1, + clobberFlags: true, + call: true, + reg: regInfo{ +@@ -24251,7 +24251,7 @@ var opcodeTable = [...]opInfo{ + { + name: "CALLinter", + auxType: auxCallOff, +- argLen: 2, ++ argLen: -1, + clobberFlags: true, + call: true, + reg: regInfo{ +-- +2.20.1 + diff --git a/loongarch64/0028-runtime-make-duff-device-as-ABIInternal-for-loong64.patch b/loongarch64/0028-runtime-make-duff-device-as-ABIInternal-for-loong64.patch new file mode 100644 index 0000000000000000000000000000000000000000..c7636cf1c6f693c15c69e4b938ac90118e2c8af9 --- /dev/null +++ b/loongarch64/0028-runtime-make-duff-device-as-ABIInternal-for-loong64.patch @@ -0,0 +1,61 @@ +From 474a79380d038bd948e31f26c4f66788a9eba1b2 Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Tue, 15 Aug 2023 20:54:16 +0800 +Subject: [PATCH 28/51] runtime: make duff device as ABIInternal for loong64 + +Update #40724 + +Co-authored-by: Xiaolin Zhao +Change-Id: Iaf7a7b7cb1897da859f59fafdedc4a249f867e98 +--- + src/runtime/duff_loong64.s | 4 ++-- + src/runtime/mkduff.go | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/src/runtime/duff_loong64.s b/src/runtime/duff_loong64.s +index df8b653965..b05502d91d 100644 +--- a/src/runtime/duff_loong64.s ++++ b/src/runtime/duff_loong64.s +@@ -4,7 +4,7 @@ + + #include "textflag.h" + +-TEXT runtime·duffzero(SB), NOSPLIT|NOFRAME, $0-0 ++TEXT runtime·duffzero(SB), NOSPLIT|NOFRAME, $0-0 + MOVV R0, (R20) + ADDV $8, R20 + MOVV R0, (R20) +@@ -263,7 +263,7 @@ TEXT runtime·duffzero(SB), NOSPLIT|NOFRAME, $0-0 + ADDV $8, R20 + RET + +-TEXT runtime·duffcopy(SB), NOSPLIT|NOFRAME, $0-0 ++TEXT runtime·duffcopy(SB), NOSPLIT|NOFRAME, $0-0 + MOVV (R20), R30 + ADDV $8, R20 + MOVV R30, (R21) +diff --git a/src/runtime/mkduff.go b/src/runtime/mkduff.go +index 77674254d4..b7f07b5087 100644 +--- a/src/runtime/mkduff.go ++++ b/src/runtime/mkduff.go +@@ -181,7 +181,7 @@ func zeroLOONG64(w io.Writer) { + // R0: always zero + // R19 (aka REGRT1): ptr to memory to be zeroed + // On return, R19 points to the last zeroed dword. +- fmt.Fprintln(w, "TEXT runtime·duffzero(SB), NOSPLIT|NOFRAME, $0-0") ++ fmt.Fprintln(w, "TEXT runtime·duffzero(SB), NOSPLIT|NOFRAME, $0-0") + for i := 0; i < 128; i++ { + fmt.Fprintln(w, "\tMOVV\tR0, (R20)") + fmt.Fprintln(w, "\tADDV\t$8, R20") +@@ -190,7 +190,7 @@ func zeroLOONG64(w io.Writer) { + } + + func copyLOONG64(w io.Writer) { +- fmt.Fprintln(w, "TEXT runtime·duffcopy(SB), NOSPLIT|NOFRAME, $0-0") ++ fmt.Fprintln(w, "TEXT runtime·duffcopy(SB), NOSPLIT|NOFRAME, $0-0") + for i := 0; i < 128; i++ { + fmt.Fprintln(w, "\tMOVV\t(R20), R30") + fmt.Fprintln(w, "\tADDV\t$8, R20") +-- +2.20.1 + diff --git a/loongarch64/0029-runtime-support-regABI-and-add-spill-functions-in-ru.patch b/loongarch64/0029-runtime-support-regABI-and-add-spill-functions-in-ru.patch new file mode 100644 index 0000000000000000000000000000000000000000..899dfbf357bbcef62f0f4f0fd1f095681025d1ab --- /dev/null +++ b/loongarch64/0029-runtime-support-regABI-and-add-spill-functions-in-ru.patch @@ -0,0 +1,462 @@ +From c7ccf1fa06eb63651ca77856b0642765b8aa1529 Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Tue, 15 Aug 2023 21:09:16 +0800 +Subject: [PATCH 29/51] runtime: support regABI and add spill functions in + runtime for loong64 + +Update #40724 + +Co-authored-by: Xiaolin Zhao +Change-Id: Ib5b0868664521035f33c1c488dccd24a5ace2186 +--- + src/runtime/asm_loong64.s | 295 ++++++++++++++++++++++++++++------- + src/runtime/stubs_loong64.go | 7 + + 2 files changed, 243 insertions(+), 59 deletions(-) + +diff --git a/src/runtime/asm_loong64.s b/src/runtime/asm_loong64.s +index 23cbd09947..0a970ef20c 100644 +--- a/src/runtime/asm_loong64.s ++++ b/src/runtime/asm_loong64.s +@@ -72,7 +72,7 @@ nocgo: + MOVV R0, 1(R0) + RET + +-DATA runtime·mainPC+0(SB)/8,$runtime·main(SB) ++DATA runtime·mainPC+0(SB)/8,$runtime·main(SB) + GLOBL runtime·mainPC(SB),RODATA,$8 + + TEXT runtime·breakpoint(SB),NOSPLIT|NOFRAME,$0-0 +@@ -123,26 +123,31 @@ TEXT gogo<>(SB), NOSPLIT|NOFRAME, $0 + // Switch to m->g0's stack, call fn(g). + // Fn must never return. It should gogo(&g->sched) + // to keep running g. +-TEXT runtime·mcall(SB), NOSPLIT|NOFRAME, $0-8 ++TEXT runtime·mcall(SB), NOSPLIT|NOFRAME, $0-8 ++#ifdef GOEXPERIMENT_regabiargs ++ MOVV R4, REGCTXT ++#else ++ MOVV fn+0(FP), REGCTXT ++#endif ++ + // Save caller state in g->sched + MOVV R3, (g_sched+gobuf_sp)(g) + MOVV R1, (g_sched+gobuf_pc)(g) + MOVV R0, (g_sched+gobuf_lr)(g) + + // Switch to m->g0 & its stack, call fn. +- MOVV g, R19 +- MOVV g_m(g), R4 +- MOVV m_g0(R4), g ++ MOVV g, R4 // arg = g ++ MOVV g_m(g), R20 ++ MOVV m_g0(R20), g + JAL runtime·save_g(SB) +- BNE g, R19, 2(PC) ++ BNE g, R4, 2(PC) + JMP runtime·badmcall(SB) +- MOVV fn+0(FP), REGCTXT // context +- MOVV 0(REGCTXT), R5 // code pointer ++ MOVV 0(REGCTXT), R20 // code pointer + MOVV (g_sched+gobuf_sp)(g), R3 // sp = m->g0->sched.sp + ADDV $-16, R3 +- MOVV R19, 8(R3) ++ MOVV R4, 8(R3) + MOVV R0, 0(R3) +- JAL (R5) ++ JAL (R20) + JMP runtime·badmcall2(SB) + + // systemstack_switch is a dummy routine that systemstack leaves at the bottom +@@ -272,7 +277,7 @@ TEXT runtime·morestack_noctxt(SB),NOSPLIT|NOFRAME,$0-0 + JMP runtime·morestack(SB) + + // reflectcall: call a function with the given argument list +-// func call(argtype *_type, f *FuncVal, arg *byte, argsize, retoffset uint32). ++// func call(stackArgsType *_type, f *FuncVal, stackArgs *byte, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs). + // we don't have variable-sized frames, so we use a small number + // of constant-sized-frame functions to encode a few bits of size in the pc. + // Caution: ugly multiline assembly macros in your future! +@@ -286,7 +291,7 @@ TEXT runtime·morestack_noctxt(SB),NOSPLIT|NOFRAME,$0-0 + // Note: can't just "BR NAME(SB)" - bad inlining results. + + TEXT ·reflectcall(SB), NOSPLIT|NOFRAME, $0-48 +- MOVWU stackArgsSize+24(FP), R19 ++ MOVWU frameSize+32(FP), R19 + DISPATCH(runtime·call32, 32) + DISPATCH(runtime·call64, 64) + DISPATCH(runtime·call128, 128) +@@ -317,7 +322,7 @@ TEXT ·reflectcall(SB), NOSPLIT|NOFRAME, $0-48 + JMP (R4) + + #define CALLFN(NAME,MAXSIZE) \ +-TEXT NAME(SB), WRAPPER, $MAXSIZE-24; \ ++TEXT NAME(SB), WRAPPER, $MAXSIZE-48; \ + NO_LOCAL_POINTERS; \ + /* copy arguments to stack */ \ + MOVV arg+16(FP), R4; \ +@@ -331,12 +336,17 @@ TEXT NAME(SB), WRAPPER, $MAXSIZE-24; \ + MOVBU R6, (R12); \ + ADDV $1, R12; \ + JMP -5(PC); \ ++ /* set up argument registers */ \ ++ MOVV regArgs+40(FP), R25; \ ++ JAL ·unspillArgs(SB); \ + /* call function */ \ + MOVV f+8(FP), REGCTXT; \ +- MOVV (REGCTXT), R6; \ ++ MOVV (REGCTXT), R25; \ + PCDATA $PCDATA_StackMapIndex, $0; \ +- JAL (R6); \ ++ JAL (R25); \ + /* copy return values back */ \ ++ MOVV regArgs+40(FP), R25; \ ++ JAL ·spillArgs(SB); \ + MOVV argtype+0(FP), R7; \ + MOVV arg+16(FP), R4; \ + MOVWU n+24(FP), R5; \ +@@ -352,11 +362,13 @@ TEXT NAME(SB), WRAPPER, $MAXSIZE-24; \ + // separate function so it can allocate stack space for the arguments + // to reflectcallmove. It does not follow the Go ABI; it expects its + // arguments in registers. +-TEXT callRet<>(SB), NOSPLIT, $32-0 ++TEXT callRet<>(SB), NOSPLIT, $40-0 ++ NO_LOCAL_POINTERS + MOVV R7, 8(R3) + MOVV R4, 16(R3) + MOVV R12, 24(R3) + MOVV R5, 32(R3) ++ MOVV R25, 40(R3) + JAL runtime·reflectcallmove(SB) + RET + +@@ -567,7 +579,7 @@ havem: + // If the m on entry wasn't nil, + // 1. the thread might be a Go thread, + // 2. or it wasn't the first call from a C thread on pthread platforms, +- // since then we skip dropm to reuse the m in the first call. ++ // since then we skip dropm to resue the m in the first call. + MOVV savedm-8(SP), R12 + BNE R12, droppedm + +@@ -604,14 +616,14 @@ TEXT runtime·abort(SB),NOSPLIT|NOFRAME,$0-0 + UNDEF + + // AES hashing not implemented for loong64 +-TEXT runtime·memhash(SB),NOSPLIT|NOFRAME,$0-32 +- JMP runtime·memhashFallback(SB) +-TEXT runtime·strhash(SB),NOSPLIT|NOFRAME,$0-24 +- JMP runtime·strhashFallback(SB) +-TEXT runtime·memhash32(SB),NOSPLIT|NOFRAME,$0-24 +- JMP runtime·memhash32Fallback(SB) +-TEXT runtime·memhash64(SB),NOSPLIT|NOFRAME,$0-24 +- JMP runtime·memhash64Fallback(SB) ++TEXT runtime·memhash(SB),NOSPLIT|NOFRAME,$0-32 ++ JMP runtime·memhashFallback(SB) ++TEXT runtime·strhash(SB),NOSPLIT|NOFRAME,$0-24 ++ JMP runtime·strhashFallback(SB) ++TEXT runtime·memhash32(SB),NOSPLIT|NOFRAME,$0-24 ++ JMP runtime·memhash32Fallback(SB) ++TEXT runtime·memhash64(SB),NOSPLIT|NOFRAME,$0-24 ++ JMP runtime·memhash64Fallback(SB) + + TEXT runtime·return0(SB), NOSPLIT, $0 + MOVW $0, R19 +@@ -658,6 +670,86 @@ TEXT ·checkASM(SB),NOSPLIT,$0-1 + MOVB R19, ret+0(FP) + RET + ++#ifdef GOEXPERIMENT_regabiargs ++// spillArgs stores return values from registers to a *internal/abi.RegArgs in R25. ++TEXT ·spillArgs(SB),NOSPLIT,$0-0 ++ MOVV R4, (0*8)(R25) ++ MOVV R5, (1*8)(R25) ++ MOVV R6, (2*8)(R25) ++ MOVV R7, (3*8)(R25) ++ MOVV R8, (4*8)(R25) ++ MOVV R9, (5*8)(R25) ++ MOVV R10, (6*8)(R25) ++ MOVV R11, (7*8)(R25) ++ MOVV R12, (8*8)(R25) ++ MOVV R13, (9*8)(R25) ++ MOVV R14, (10*8)(R25) ++ MOVV R15, (11*8)(R25) ++ MOVV R16, (12*8)(R25) ++ MOVV R17, (13*8)(R25) ++ MOVV R18, (14*8)(R25) ++ MOVV R19, (15*8)(R25) ++ MOVD F0, (16*8)(R25) ++ MOVD F1, (17*8)(R25) ++ MOVD F2, (18*8)(R25) ++ MOVD F3, (19*8)(R25) ++ MOVD F4, (20*8)(R25) ++ MOVD F5, (21*8)(R25) ++ MOVD F6, (22*8)(R25) ++ MOVD F7, (23*8)(R25) ++ MOVD F8, (24*8)(R25) ++ MOVD F9, (25*8)(R25) ++ MOVD F10, (26*8)(R25) ++ MOVD F11, (27*8)(R25) ++ MOVD F12, (28*8)(R25) ++ MOVD F13, (29*8)(R25) ++ MOVD F14, (30*8)(R25) ++ MOVD F15, (31*8)(R25) ++ RET ++ ++// unspillArgs loads args into registers from a *internal/abi.RegArgs in R25. ++TEXT ·unspillArgs(SB),NOSPLIT,$0-0 ++ MOVV (0*8)(R25), R4 ++ MOVV (1*8)(R25), R5 ++ MOVV (2*8)(R25), R6 ++ MOVV (3*8)(R25), R7 ++ MOVV (4*8)(R25), R8 ++ MOVV (5*8)(R25), R9 ++ MOVV (6*8)(R25), R10 ++ MOVV (7*8)(R25), R11 ++ MOVV (8*8)(R25), R12 ++ MOVV (9*8)(R25), R13 ++ MOVV (10*8)(R25), R14 ++ MOVV (11*8)(R25), R15 ++ MOVV (12*8)(R25), R16 ++ MOVV (13*8)(R25), R17 ++ MOVV (14*8)(R25), R18 ++ MOVV (15*8)(R25), R19 ++ MOVD (16*8)(R25), F0 ++ MOVD (17*8)(R25), F1 ++ MOVD (18*8)(R25), F2 ++ MOVD (19*8)(R25), F3 ++ MOVD (20*8)(R25), F4 ++ MOVD (21*8)(R25), F5 ++ MOVD (22*8)(R25), F6 ++ MOVD (23*8)(R25), F7 ++ MOVD (24*8)(R25), F8 ++ MOVD (25*8)(R25), F9 ++ MOVD (26*8)(R25), F10 ++ MOVD (27*8)(R25), F11 ++ MOVD (28*8)(R25), F12 ++ MOVD (29*8)(R25), F13 ++ MOVD (30*8)(R25), F14 ++ MOVD (31*8)(R25), F15 ++ RET ++#else ++TEXT ·spillArgs(SB),NOSPLIT,$0-0 ++ RET ++ ++TEXT ·unspillArgs(SB),NOSPLIT,$0-0 ++ RET ++#endif ++ + // gcWriteBarrier informs the GC about heap pointer writes. + // + // gcWriteBarrier does NOT follow the Go ABI. It accepts the +@@ -785,71 +877,156 @@ TEXT runtime·gcWriteBarrier8(SB),NOSPLIT,$0 + // in the caller's stack frame. These stubs write the args into that stack space and + // then tail call to the corresponding runtime handler. + // The tail call makes these stubs disappear in backtraces. +-TEXT runtime·panicIndex(SB),NOSPLIT,$0-16 ++TEXT runtime·panicIndex(SB),NOSPLIT,$0-16 ++#ifdef GOEXPERIMENT_regabiargs ++ MOVV R20, R4 ++ MOVV R21, R5 ++#else + MOVV R20, x+0(FP) + MOVV R21, y+8(FP) +- JMP runtime·goPanicIndex(SB) +-TEXT runtime·panicIndexU(SB),NOSPLIT,$0-16 ++#endif ++ JMP runtime·goPanicIndex(SB) ++TEXT runtime·panicIndexU(SB),NOSPLIT,$0-16 ++#ifdef GOEXPERIMENT_regabiargs ++ MOVV R20, R4 ++ MOVV R21, R5 ++#else + MOVV R20, x+0(FP) + MOVV R21, y+8(FP) +- JMP runtime·goPanicIndexU(SB) +-TEXT runtime·panicSliceAlen(SB),NOSPLIT,$0-16 ++#endif ++ JMP runtime·goPanicIndexU(SB) ++TEXT runtime·panicSliceAlen(SB),NOSPLIT,$0-16 ++#ifdef GOEXPERIMENT_regabiargs ++ MOVV R21, R4 ++ MOVV R23, R5 ++#else + MOVV R21, x+0(FP) + MOVV R23, y+8(FP) +- JMP runtime·goPanicSliceAlen(SB) +-TEXT runtime·panicSliceAlenU(SB),NOSPLIT,$0-16 ++#endif ++ JMP runtime·goPanicSliceAlen(SB) ++TEXT runtime·panicSliceAlenU(SB),NOSPLIT,$0-16 ++#ifdef GOEXPERIMENT_regabiargs ++ MOVV R21, R4 ++ MOVV R23, R5 ++#else + MOVV R21, x+0(FP) + MOVV R23, y+8(FP) +- JMP runtime·goPanicSliceAlenU(SB) +-TEXT runtime·panicSliceAcap(SB),NOSPLIT,$0-16 ++#endif ++ JMP runtime·goPanicSliceAlenU(SB) ++TEXT runtime·panicSliceAcap(SB),NOSPLIT,$0-16 ++#ifdef GOEXPERIMENT_regabiargs ++ MOVV R21, R4 ++ MOVV R23, R5 ++#else + MOVV R21, x+0(FP) + MOVV R23, y+8(FP) +- JMP runtime·goPanicSliceAcap(SB) +-TEXT runtime·panicSliceAcapU(SB),NOSPLIT,$0-16 ++#endif ++ JMP runtime·goPanicSliceAcap(SB) ++TEXT runtime·panicSliceAcapU(SB),NOSPLIT,$0-16 ++#ifdef GOEXPERIMENT_regabiargs ++ MOVV R21, R4 ++ MOVV R23, R5 ++#else + MOVV R21, x+0(FP) + MOVV R23, y+8(FP) +- JMP runtime·goPanicSliceAcapU(SB) +-TEXT runtime·panicSliceB(SB),NOSPLIT,$0-16 ++#endif ++ JMP runtime·goPanicSliceAcapU(SB) ++TEXT runtime·panicSliceB(SB),NOSPLIT,$0-16 ++#ifdef GOEXPERIMENT_regabiargs ++ MOVV R20, R4 ++ MOVV R21, R5 ++#else + MOVV R20, x+0(FP) + MOVV R21, y+8(FP) +- JMP runtime·goPanicSliceB(SB) +-TEXT runtime·panicSliceBU(SB),NOSPLIT,$0-16 ++#endif ++ JMP runtime·goPanicSliceB(SB) ++TEXT runtime·panicSliceBU(SB),NOSPLIT,$0-16 ++#ifdef GOEXPERIMENT_regabiargs ++ MOVV R20, R4 ++ MOVV R21, R5 ++#else + MOVV R20, x+0(FP) + MOVV R21, y+8(FP) +- JMP runtime·goPanicSliceBU(SB) +-TEXT runtime·panicSlice3Alen(SB),NOSPLIT,$0-16 ++#endif ++ JMP runtime·goPanicSliceBU(SB) ++TEXT runtime·panicSlice3Alen(SB),NOSPLIT,$0-16 ++#ifdef GOEXPERIMENT_regabiargs ++ MOVV R23, R4 ++ MOVV R24, R5 ++#else + MOVV R23, x+0(FP) + MOVV R24, y+8(FP) +- JMP runtime·goPanicSlice3Alen(SB) +-TEXT runtime·panicSlice3AlenU(SB),NOSPLIT,$0-16 ++#endif ++ JMP runtime·goPanicSlice3Alen(SB) ++TEXT runtime·panicSlice3AlenU(SB),NOSPLIT,$0-16 ++#ifdef GOEXPERIMENT_regabiargs ++ MOVV R23, R4 ++ MOVV R24, R5 ++#else + MOVV R23, x+0(FP) + MOVV R24, y+8(FP) +- JMP runtime·goPanicSlice3AlenU(SB) +-TEXT runtime·panicSlice3Acap(SB),NOSPLIT,$0-16 ++#endif ++ JMP runtime·goPanicSlice3AlenU(SB) ++TEXT runtime·panicSlice3Acap(SB),NOSPLIT,$0-16 ++#ifdef GOEXPERIMENT_regabiargs ++ MOVV R23, R4 ++ MOVV R24, R5 ++#else + MOVV R23, x+0(FP) + MOVV R24, y+8(FP) +- JMP runtime·goPanicSlice3Acap(SB) +-TEXT runtime·panicSlice3AcapU(SB),NOSPLIT,$0-16 ++#endif ++ JMP runtime·goPanicSlice3Acap(SB) ++TEXT runtime·panicSlice3AcapU(SB),NOSPLIT,$0-16 ++#ifdef GOEXPERIMENT_regabiargs ++ MOVV R23, R4 ++ MOVV R24, R5 ++#else + MOVV R23, x+0(FP) + MOVV R24, y+8(FP) +- JMP runtime·goPanicSlice3AcapU(SB) +-TEXT runtime·panicSlice3B(SB),NOSPLIT,$0-16 ++#endif ++ JMP runtime·goPanicSlice3AcapU(SB) ++TEXT runtime·panicSlice3B(SB),NOSPLIT,$0-16 ++#ifdef GOEXPERIMENT_regabiargs ++ MOVV R21, R4 ++ MOVV R23, R5 ++#else + MOVV R21, x+0(FP) + MOVV R23, y+8(FP) +- JMP runtime·goPanicSlice3B(SB) +-TEXT runtime·panicSlice3BU(SB),NOSPLIT,$0-16 ++#endif ++ JMP runtime·goPanicSlice3B(SB) ++TEXT runtime·panicSlice3BU(SB),NOSPLIT,$0-16 ++#ifdef GOEXPERIMENT_regabiargs ++ MOVV R21, R4 ++ MOVV R23, R5 ++#else + MOVV R21, x+0(FP) + MOVV R23, y+8(FP) +- JMP runtime·goPanicSlice3BU(SB) +-TEXT runtime·panicSlice3C(SB),NOSPLIT,$0-16 ++#endif ++ JMP runtime·goPanicSlice3BU(SB) ++TEXT runtime·panicSlice3C(SB),NOSPLIT,$0-16 ++#ifdef GOEXPERIMENT_regabiargs ++ MOVV R20, R4 ++ MOVV R21, R5 ++#else + MOVV R20, x+0(FP) + MOVV R21, y+8(FP) +- JMP runtime·goPanicSlice3C(SB) +-TEXT runtime·panicSlice3CU(SB),NOSPLIT,$0-16 ++#endif ++ JMP runtime·goPanicSlice3C(SB) ++TEXT runtime·panicSlice3CU(SB),NOSPLIT,$0-16 ++#ifdef GOEXPERIMENT_regabiargs ++ MOVV R20, R4 ++ MOVV R21, R5 ++#else + MOVV R20, x+0(FP) + MOVV R21, y+8(FP) +- JMP runtime·goPanicSlice3CU(SB) +-TEXT runtime·panicSliceConvert(SB),NOSPLIT,$0-16 ++#endif ++ JMP runtime·goPanicSlice3CU(SB) ++TEXT runtime·panicSliceConvert(SB),NOSPLIT,$0-16 ++#ifdef GOEXPERIMENT_regabiargs ++ MOVV R23, R4 ++ MOVV R24, R5 ++#else + MOVV R23, x+0(FP) + MOVV R24, y+8(FP) +- JMP runtime·goPanicSliceConvert(SB) ++#endif ++ JMP runtime·goPanicSliceConvert(SB) +diff --git a/src/runtime/stubs_loong64.go b/src/runtime/stubs_loong64.go +index 556983cad1..4576089b0b 100644 +--- a/src/runtime/stubs_loong64.go ++++ b/src/runtime/stubs_loong64.go +@@ -10,6 +10,13 @@ package runtime + func load_g() + func save_g() + ++// Used by reflectcall and the reflect package. ++// ++// Spills/loads arguments in registers to/from an internal/abi.RegArgs ++// respectively. Does not follow the Go ABI. ++func spillArgs() ++func unspillArgs() ++ + // getfp returns the frame pointer register of its caller or 0 if not implemented. + // TODO: Make this a compiler intrinsic + func getfp() uintptr { return 0 } +-- +2.20.1 + diff --git a/loongarch64/0030-reflect-runtime-add-reflect-support-for-regABI-on-lo.patch b/loongarch64/0030-reflect-runtime-add-reflect-support-for-regABI-on-lo.patch new file mode 100644 index 0000000000000000000000000000000000000000..4f321bb283373633362f6e1317d57181755fc779 --- /dev/null +++ b/loongarch64/0030-reflect-runtime-add-reflect-support-for-regABI-on-lo.patch @@ -0,0 +1,133 @@ +From dab8e1c2b899e0d191b01af0cea2eb60d609487d Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Wed, 16 Aug 2023 08:28:28 +0800 +Subject: [PATCH 30/51] reflect, runtime: add reflect support for regABI on + loong64 + +Update #40724 + +Co-authored-by: Xiaolin Zhao +Change-Id: I9fd6eb122db91c0ac89e9d919d5d56a106d79fe4 +--- + src/reflect/asm_loong64.s | 77 ++++++++++++++++++++++++++++++++------- + src/runtime/stkframe.go | 2 +- + 2 files changed, 64 insertions(+), 15 deletions(-) + +diff --git a/src/reflect/asm_loong64.s b/src/reflect/asm_loong64.s +index 341a6d55c1..520f0afdd5 100644 +--- a/src/reflect/asm_loong64.s ++++ b/src/reflect/asm_loong64.s +@@ -7,34 +7,83 @@ + + #define REGCTXT R29 + ++// The frames of each of the two functions below contain two locals, at offsets ++// that are known to the runtime. ++// ++// The first local is a bool called retValid with a whole pointer-word reserved ++// for it on the stack. The purpose of this word is so that the runtime knows ++// whether the stack-allocated return space contains valid values for stack ++// scanning. ++// ++// The second local is an abi.RegArgs value whose offset is also known to the ++// runtime, so that a stack map for it can be constructed, since it contains ++// pointers visible to the GC. ++#define LOCAL_RETVALID 40 ++#define LOCAL_REGARGS 48 ++ ++// The frame size of the functions below is ++// 32 (args of callReflect) + 8 (bool + padding) + 392 (abi.RegArgs) = 432. ++ + // makeFuncStub is the code half of the function returned by MakeFunc. + // See the comment on the declaration of makeFuncStub in makefunc.go + // for more details. + // No arg size here, runtime pulls arg map out of the func value. +-TEXT ·makeFuncStub(SB),(NOSPLIT|WRAPPER),$40 ++TEXT ·makeFuncStub(SB),(NOSPLIT|WRAPPER),$432 + NO_LOCAL_POINTERS ++ ADDV $LOCAL_REGARGS, R3, R25 // spillArgs using R25 ++ JAL runtime·spillArgs(SB) ++ MOVV REGCTXT, 32(R3) // save REGCTXT > args of moveMakeFuncArgPtrs < LOCAL_REGARGS ++ ++#ifdef GOEXPERIMENT_regabiargs ++ MOVV REGCTXT, R4 ++ MOVV R25, R5 ++#else + MOVV REGCTXT, 8(R3) +- MOVV $argframe+0(FP), R19 +- MOVV R19, 16(R3) +- MOVB R0, 40(R3) +- ADDV $40, R3, R19 +- MOVV R19, 24(R3) +- MOVV R0, 32(R3) ++ MOVV R25, 16(R3) ++#endif ++ JAL ·moveMakeFuncArgPtrs(SB) ++ MOVV 32(R3), REGCTXT // restore REGCTXT ++ ++ MOVV REGCTXT, 8(R3) ++ MOVV $argframe+0(FP), R20 ++ MOVV R20, 16(R3) ++ MOVV R0, LOCAL_RETVALID(R3) ++ ADDV $LOCAL_RETVALID, R3, R20 ++ MOVV R20, 24(R3) ++ ADDV $LOCAL_REGARGS, R3, R20 ++ MOVV R20, 32(R3) + JAL ·callReflect(SB) ++ ADDV $LOCAL_REGARGS, R3, R25 //unspillArgs using R25 ++ JAL runtime·unspillArgs(SB) + RET + + // methodValueCall is the code half of the function returned by makeMethodValue. + // See the comment on the declaration of methodValueCall in makefunc.go + // for more details. + // No arg size here; runtime pulls arg map out of the func value. +-TEXT ·methodValueCall(SB),(NOSPLIT|WRAPPER),$40 ++TEXT ·methodValueCall(SB),(NOSPLIT|WRAPPER),$432 + NO_LOCAL_POINTERS ++ ADDV $LOCAL_REGARGS, R3, R25 // spillArgs using R25 ++ JAL runtime·spillArgs(SB) ++ MOVV REGCTXT, 32(R3) // save REGCTXT > args of moveMakeFuncArgPtrs < LOCAL_REGARGS ++#ifdef GOEXPERIMENT_regabiargs ++ MOVV REGCTXT, R4 ++ MOVV R25, R5 ++#else ++ MOVV REGCTXT, 8(R3) ++ MOVV R25, 16(R3) ++#endif ++ JAL ·moveMakeFuncArgPtrs(SB) ++ MOVV 32(R3), REGCTXT // restore REGCTXT + MOVV REGCTXT, 8(R3) +- MOVV $argframe+0(FP), R19 +- MOVV R19, 16(R3) +- MOVB R0, 40(R3) +- ADDV $40, R3, R19 +- MOVV R19, 24(R3) +- MOVV R0, 32(R3) ++ MOVV $argframe+0(FP), R20 ++ MOVV R20, 16(R3) ++ MOVB R0, LOCAL_RETVALID(R3) ++ ADDV $LOCAL_RETVALID, R3, R20 ++ MOVV R20, 24(R3) ++ ADDV $LOCAL_REGARGS, R3, R20 ++ MOVV R20, 32(R3) // frame size to 32+SP as callreflect args) + JAL ·callMethod(SB) ++ ADDV $LOCAL_REGARGS, R3, R25 // unspillArgs using R25 ++ JAL runtime·unspillArgs(SB) + RET +diff --git a/src/runtime/stkframe.go b/src/runtime/stkframe.go +index 5caacbacba..eca419c674 100644 +--- a/src/runtime/stkframe.go ++++ b/src/runtime/stkframe.go +@@ -234,7 +234,7 @@ func (frame *stkframe) getStackMap(cache *pcvalueCache, debug bool) (locals, arg + } + + // stack objects. +- if (GOARCH == "amd64" || GOARCH == "arm64" || GOARCH == "ppc64" || GOARCH == "ppc64le" || GOARCH == "riscv64") && ++ if (GOARCH == "amd64" || GOARCH == "arm64" || GOARCH == "loong64" || GOARCH == "ppc64" || GOARCH == "ppc64le" || GOARCH == "riscv64") && + unsafe.Sizeof(abi.RegArgs{}) > 0 && isReflect { + // For reflect.makeFuncStub and reflect.methodValueCall, + // we need to fake the stack object record. +-- +2.20.1 + diff --git a/loongarch64/0031-internal-bytealg-add-regABI-support-in-bytealg-funct.patch b/loongarch64/0031-internal-bytealg-add-regABI-support-in-bytealg-funct.patch new file mode 100644 index 0000000000000000000000000000000000000000..5d159d631dab92ea7485f3e2aab9c2b7aa2644b9 --- /dev/null +++ b/loongarch64/0031-internal-bytealg-add-regABI-support-in-bytealg-funct.patch @@ -0,0 +1,307 @@ +From 55e237f991ed4f85e611c303492d6c694ce0ff35 Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Wed, 16 Aug 2023 08:55:13 +0800 +Subject: [PATCH 31/51] internal/bytealg: add regABI support in bytealg + functions on loong64 + +Update #40724 + +Co-authored-by: Xiaolin Zhao +Change-Id: Ie9d5c39e8a1e011ed90ad78bc5bfa98a9cff3a0d +--- + src/internal/bytealg/compare_loong64.s | 95 ++++++++++++++---------- + src/internal/bytealg/equal_loong64.s | 21 +++++- + src/internal/bytealg/indexbyte_loong64.s | 32 ++++++-- + 3 files changed, 101 insertions(+), 47 deletions(-) + +diff --git a/src/internal/bytealg/compare_loong64.s b/src/internal/bytealg/compare_loong64.s +index c89c5a9256..311449ab18 100644 +--- a/src/internal/bytealg/compare_loong64.s ++++ b/src/internal/bytealg/compare_loong64.s +@@ -5,83 +5,102 @@ + #include "go_asm.h" + #include "textflag.h" + +-TEXT ·Compare(SB),NOSPLIT,$0-56 +- MOVV a_base+0(FP), R6 +- MOVV b_base+24(FP), R7 +- MOVV a_len+8(FP), R4 +- MOVV b_len+32(FP), R5 ++TEXT ·Compare(SB),NOSPLIT,$0-56 ++#ifndef GOEXPERIMENT_regabiargs ++ MOVV a_base+0(FP), R4 ++ MOVV a_len+8(FP), R5 ++ MOVV b_base+24(FP), R6 ++ MOVV b_len+32(FP), R7 + MOVV $ret+48(FP), R13 ++#else ++ // R4 = a_base ++ // R5 = a_len ++ // R6 = a_cap (unused) ++ // R7 = b_base (want in R6) ++ // R8 = b_len (want in R7) ++ // R9 = b_cap (unused) ++ MOVV R7, R6 ++ MOVV R8, R7 ++#endif + JMP cmpbody<>(SB) + +-TEXT runtime·cmpstring(SB),NOSPLIT,$0-40 +- MOVV a_base+0(FP), R6 +- MOVV b_base+16(FP), R7 +- MOVV a_len+8(FP), R4 +- MOVV b_len+24(FP), R5 ++TEXT runtime·cmpstring(SB),NOSPLIT,$0-40 ++#ifndef GOEXPERIMENT_regabiargs ++ MOVV a_base+0(FP), R4 ++ MOVV b_base+16(FP), R6 ++ MOVV a_len+8(FP), R5 ++ MOVV b_len+24(FP), R7 + MOVV $ret+32(FP), R13 ++#endif ++ // R4 = a_base ++ // R5 = a_len ++ // R6 = b_base ++ // R7 = b_len + JMP cmpbody<>(SB) + + // On entry: +-// R4 length of a +-// R5 length of b +-// R6 points to the start of a +-// R7 points to the start of b ++// R5 length of a ++// R7 length of b ++// R4 points to the start of a ++// R6 points to the start of b + // R13 points to the return value (-1/0/1) + TEXT cmpbody<>(SB),NOSPLIT|NOFRAME,$0 +- BEQ R6, R7, samebytes // same start of a and b ++ BEQ R4, R6, samebytes // same start of a and b + +- SGTU R4, R5, R9 ++ SGTU R5, R7, R9 + BNE R0, R9, r2_lt_r1 +- MOVV R4, R14 ++ MOVV R5, R14 + JMP entry + r2_lt_r1: +- MOVV R5, R14 // R14 is min(R4, R5) ++ MOVV R7, R14 // R14 is min(R4, R5) + entry: +- ADDV R6, R14, R12 // R6 start of a, R14 end of a +- BEQ R6, R12, samebytes // length is 0 ++ ADDV R4, R14, R12 // R6 start of a, R14 end of a ++ BEQ R4, R12, samebytes // length is 0 + + SRLV $4, R14 // R14 is number of chunks + BEQ R0, R14, byte_loop + + // make sure both a and b are aligned. +- OR R6, R7, R15 ++ OR R4, R6, R15 + AND $7, R15 + BNE R0, R15, byte_loop + + PCALIGN $16 + chunk16_loop: + BEQ R0, R14, byte_loop +- MOVV (R6), R8 +- MOVV (R7), R9 ++ MOVV (R4), R8 ++ MOVV (R6), R9 + BNE R8, R9, byte_loop +- MOVV 8(R6), R16 +- MOVV 8(R7), R17 ++ MOVV 8(R4), R16 ++ MOVV 8(R6), R17 ++ ADDV $16, R4 + ADDV $16, R6 +- ADDV $16, R7 + SUBVU $1, R14 + BEQ R16, R17, chunk16_loop ++ SUBV $8, R4 + SUBV $8, R6 +- SUBV $8, R7 + + byte_loop: +- BEQ R6, R12, samebytes +- MOVBU (R6), R8 ++ BEQ R4, R12, samebytes ++ MOVBU (R4), R8 ++ ADDVU $1, R4 ++ MOVBU (R6), R9 + ADDVU $1, R6 +- MOVBU (R7), R9 +- ADDVU $1, R7 + BEQ R8, R9, byte_loop + + byte_cmp: +- SGTU R8, R9, R12 // R12 = 1 if (R8 > R9) +- BNE R0, R12, ret +- MOVV $-1, R12 ++ SGTU R8, R9, R4 // R12 = 1 if (R8 > R9) ++ BNE R0, R4, ret ++ MOVV $-1, R4 + JMP ret + + samebytes: +- SGTU R4, R5, R8 +- SGTU R5, R4, R9 +- SUBV R9, R8, R12 ++ SGTU R5, R7, R8 ++ SGTU R7, R5, R9 ++ SUBV R9, R8, R4 + + ret: +- MOVV R12, (R13) ++#ifndef GOEXPERIMENT_regabiargs ++ MOVV R4, (R13) ++#endif + RET +diff --git a/src/internal/bytealg/equal_loong64.s b/src/internal/bytealg/equal_loong64.s +index ba2a5578c3..a3ad5c1b35 100644 +--- a/src/internal/bytealg/equal_loong64.s ++++ b/src/internal/bytealg/equal_loong64.s +@@ -8,17 +8,21 @@ + #define REGCTXT R29 + + // memequal(a, b unsafe.Pointer, size uintptr) bool +-TEXT runtime·memequal(SB),NOSPLIT|NOFRAME,$0-25 ++TEXT runtime·memequal(SB),NOSPLIT|NOFRAME,$0-25 ++#ifndef GOEXPERIMENT_regabiargs + MOVV a+0(FP), R4 + MOVV b+8(FP), R5 +- BEQ R4, R5, eq + MOVV size+16(FP), R6 ++#endif ++ BEQ R4, R5, eq + ADDV R4, R6, R7 + PCALIGN $16 + loop: + BNE R4, R7, test + MOVV $1, R4 ++#ifndef GOEXPERIMENT_regabiargs + MOVB R4, ret+24(FP) ++#endif + RET + test: + MOVBU (R4), R9 +@@ -27,17 +31,24 @@ test: + ADDV $1, R5 + BEQ R9, R10, loop + ++ MOVB R0, R4 ++#ifndef GOEXPERIMENT_regabiargs + MOVB R0, ret+24(FP) ++#endif + RET + eq: + MOVV $1, R4 ++#ifndef GOEXPERIMENT_regabiargs + MOVB R4, ret+24(FP) ++#endif + RET + + // memequal_varlen(a, b unsafe.Pointer) bool +-TEXT runtime·memequal_varlen(SB),NOSPLIT,$40-17 ++TEXT runtime·memequal_varlen(SB),NOSPLIT,$40-17 ++#ifndef GOEXPERIMENT_regabiargs + MOVV a+0(FP), R4 + MOVV b+8(FP), R5 ++#endif + BEQ R4, R5, eq + MOVV 8(REGCTXT), R6 // compiler stores size at offset 8 in the closure + MOVV R4, 8(R3) +@@ -45,9 +56,13 @@ TEXT runtime·memequal_varlen(SB),NOSPLIT,$40-17 + MOVV R6, 24(R3) + JAL runtime·memequal(SB) + MOVBU 32(R3), R4 ++#ifndef GOEXPERIMENT_regabiargs + MOVB R4, ret+16(FP) ++#endif + RET + eq: + MOVV $1, R4 ++#ifndef GOEXPERIMENT_regabiargs + MOVB R4, ret+16(FP) ++#endif + RET +diff --git a/src/internal/bytealg/indexbyte_loong64.s b/src/internal/bytealg/indexbyte_loong64.s +index 604970549f..03e0660973 100644 +--- a/src/internal/bytealg/indexbyte_loong64.s ++++ b/src/internal/bytealg/indexbyte_loong64.s +@@ -5,11 +5,18 @@ + #include "go_asm.h" + #include "textflag.h" + +-TEXT ·IndexByte(SB),NOSPLIT,$0-40 ++TEXT ·IndexByte(SB),NOSPLIT,$0-40 ++#ifndef GOEXPERIMENT_regabiargs + MOVV b_base+0(FP), R4 + MOVV b_len+8(FP), R5 +- MOVBU c+24(FP), R6 // byte to find +- MOVV R4, R7 // store base for later ++ MOVBU c+24(FP), R7 // byte to find ++#endif ++ // R4 = b_base ++ // R5 = b_len ++ // R6 = b_cap (unused) ++ // R7 = byte to find ++ AND $0xff, R7 ++ MOVV R4, R6 // store base for later + ADDV R4, R5 // end + ADDV $-1, R4 + +@@ -18,21 +25,30 @@ loop: + ADDV $1, R4 + BEQ R4, R5, notfound + MOVBU (R4), R8 +- BNE R6, R8, loop ++ BNE R7, R8, loop + +- SUBV R7, R4 // remove base ++ SUBV R6, R4 // remove base ++#ifndef GOEXPERIMENT_regabiargs + MOVV R4, ret+32(FP) ++#endif + RET + + notfound: + MOVV $-1, R4 ++#ifndef GOEXPERIMENT_regabiargs + MOVV R4, ret+32(FP) ++#endif + RET + +-TEXT ·IndexByteString(SB),NOSPLIT,$0-32 ++TEXT ·IndexByteString(SB),NOSPLIT,$0-32 ++#ifndef GOEXPERIMENT_regabiargs + MOVV s_base+0(FP), R4 + MOVV s_len+8(FP), R5 + MOVBU c+16(FP), R6 // byte to find ++#endif ++ // R4 = s_base ++ // R5 = s_len ++ // R6 = byte to find + MOVV R4, R7 // store base for later + ADDV R4, R5 // end + ADDV $-1, R4 +@@ -45,10 +61,14 @@ loop: + BNE R6, R8, loop + + SUBV R7, R4 // remove base ++#ifndef GOEXPERIMENT_regabiargs + MOVV R4, ret+24(FP) ++#endif + RET + + notfound: + MOVV $-1, R4 ++#ifndef GOEXPERIMENT_regabiargs + MOVV R4, ret+24(FP) ++#endif + RET +-- +2.20.1 + diff --git a/loongarch64/0032-runtime-add-regABI-support-in-memclr-and-memmove-fun.patch b/loongarch64/0032-runtime-add-regABI-support-in-memclr-and-memmove-fun.patch new file mode 100644 index 0000000000000000000000000000000000000000..eb6295483cee34c7529ad8b1d7d7ebc197f1b62f --- /dev/null +++ b/loongarch64/0032-runtime-add-regABI-support-in-memclr-and-memmove-fun.patch @@ -0,0 +1,95 @@ +From 6980d54baf4184cc9fd79e2135be33721efc6e62 Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Wed, 16 Aug 2023 09:05:30 +0800 +Subject: [PATCH 32/51] runtime: add regABI support in memclr and memmove + functions on loong64 + +Update #40724 + +Co-authored-by: Xiaolin Zhao +Change-Id: I2ff3421da41de4e1a88538e67c9baa26bcf6ffc0 +--- + src/runtime/memclr_loong64.s | 32 +++++++++++++++++--------------- + src/runtime/memmove_loong64.s | 4 +++- + 2 files changed, 20 insertions(+), 16 deletions(-) + +diff --git a/src/runtime/memclr_loong64.s b/src/runtime/memclr_loong64.s +index 7bb6f3dfc9..313e4d4f33 100644 +--- a/src/runtime/memclr_loong64.s ++++ b/src/runtime/memclr_loong64.s +@@ -6,37 +6,39 @@ + #include "textflag.h" + + // func memclrNoHeapPointers(ptr unsafe.Pointer, n uintptr) +-TEXT runtime·memclrNoHeapPointers(SB),NOSPLIT,$0-16 +- MOVV ptr+0(FP), R6 +- MOVV n+8(FP), R7 +- ADDV R6, R7, R4 ++TEXT runtime·memclrNoHeapPointers(SB),NOSPLIT,$0-16 ++#ifndef GOEXPERIMENT_regabiargs ++ MOVV ptr+0(FP), R4 ++ MOVV n+8(FP), R5 ++#endif ++ ADDV R4, R5, R6 + + // if less than 8 bytes, do one byte at a time +- SGTU $8, R7, R8 ++ SGTU $8, R5, R8 + BNE R8, out + + // do one byte at a time until 8-aligned +- AND $7, R6, R8 ++ AND $7, R4, R8 + BEQ R8, words +- MOVB R0, (R6) +- ADDV $1, R6 ++ MOVB R0, (R4) ++ ADDV $1, R4 + JMP -4(PC) + + words: + // do 8 bytes at a time if there is room +- ADDV $-7, R4, R7 ++ ADDV $-7, R6, R5 + + PCALIGN $16 +- SGTU R7, R6, R8 ++ SGTU R5, R4, R8 + BEQ R8, out +- MOVV R0, (R6) +- ADDV $8, R6 ++ MOVV R0, (R4) ++ ADDV $8, R4 + JMP -4(PC) + + out: +- BEQ R6, R4, done +- MOVB R0, (R6) +- ADDV $1, R6 ++ BEQ R4, R6, done ++ MOVB R0, (R4) ++ ADDV $1, R4 + JMP -3(PC) + done: + RET +diff --git a/src/runtime/memmove_loong64.s b/src/runtime/memmove_loong64.s +index 0f139bcc13..5b7aeba698 100644 +--- a/src/runtime/memmove_loong64.s ++++ b/src/runtime/memmove_loong64.s +@@ -7,10 +7,12 @@ + // See memmove Go doc for important implementation constraints. + + // func memmove(to, from unsafe.Pointer, n uintptr) +-TEXT runtime·memmove(SB), NOSPLIT|NOFRAME, $0-24 ++TEXT runtime·memmove(SB), NOSPLIT|NOFRAME, $0-24 ++#ifndef GOEXPERIMENT_regabiargs + MOVV to+0(FP), R4 + MOVV from+8(FP), R5 + MOVV n+16(FP), R6 ++#endif + BNE R6, check + RET + +-- +2.20.1 + diff --git a/loongarch64/0033-cmd-internal-obj-set-morestack-arg-spilling-and-rega.patch b/loongarch64/0033-cmd-internal-obj-set-morestack-arg-spilling-and-rega.patch new file mode 100644 index 0000000000000000000000000000000000000000..512f2ff4481f9c47e209d5b3827dda4b56bac130 --- /dev/null +++ b/loongarch64/0033-cmd-internal-obj-set-morestack-arg-spilling-and-rega.patch @@ -0,0 +1,60 @@ +From 0b52907e2fc77c58b8f67897b784651b2a1aded7 Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Wed, 16 Aug 2023 09:16:21 +0800 +Subject: [PATCH 33/51] cmd/internal/obj: set morestack arg spilling and regabi + prologue on loong64 + +Update #40724 + +Co-authored-by: Xiaolin Zhao +Change-Id: I60bd80818d7f308b05a3f11d71a552ddf6fa5086 +--- + src/cmd/internal/obj/loong64/obj.go | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/src/cmd/internal/obj/loong64/obj.go b/src/cmd/internal/obj/loong64/obj.go +index b0f5ac3087..ed5165418d 100644 +--- a/src/cmd/internal/obj/loong64/obj.go ++++ b/src/cmd/internal/obj/loong64/obj.go +@@ -626,6 +626,10 @@ func (c *ctxt0) stacksplit(p *obj.Prog, framesize int32) *obj.Prog { + + p = c.ctxt.StartUnsafePoint(p, c.newprog) + ++ // Spill Arguments. This has to happen before we open ++ // any more frame space. ++ p = c.cursym.Func().SpillRegisterArgs(p, c.newprog) ++ + // MOV REGLINK, -8/-16(SP) + p = obj.Appendp(p, c.newprog) + p.As = mov +@@ -690,6 +694,8 @@ func (c *ctxt0) stacksplit(p *obj.Prog, framesize int32) *obj.Prog { + p.To.Reg = REGSP + p.Spadj = int32(-frameSize) + ++ // Unspill arguments ++ p = c.cursym.Func().UnspillRegisterArgs(p, c.newprog) + p = c.ctxt.EndUnsafePoint(p, c.newprog, -1) + } + +@@ -801,6 +807,10 @@ func (c *ctxt0) stacksplit(p *obj.Prog, framesize int32) *obj.Prog { + + p = c.ctxt.EmitEntryStackMap(c.cursym, p, c.newprog) + ++ // Spill the register args that could be clobbered by the ++ // morestack code ++ p = c.cursym.Func().SpillRegisterArgs(p, c.newprog) ++ + // JAL runtime.morestack(SB) + p = obj.Appendp(p, c.newprog) + +@@ -815,6 +825,7 @@ func (c *ctxt0) stacksplit(p *obj.Prog, framesize int32) *obj.Prog { + } + p.Mark |= BRANCH + ++ p = c.cursym.Func().UnspillRegisterArgs(p, c.newprog) + p = c.ctxt.EndUnsafePoint(p, c.newprog, -1) + + // JMP start +-- +2.20.1 + diff --git a/loongarch64/0034-cmd-compile-fix-If-lowering-on-loong64.patch b/loongarch64/0034-cmd-compile-fix-If-lowering-on-loong64.patch new file mode 100644 index 0000000000000000000000000000000000000000..21d71632bfa73ad6952fcd3479f5a4fa7d2fd6c8 --- /dev/null +++ b/loongarch64/0034-cmd-compile-fix-If-lowering-on-loong64.patch @@ -0,0 +1,92 @@ +From 956ecf0d8131760f371db184e497cb5a033f7dbe Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Wed, 16 Aug 2023 10:22:13 +0800 +Subject: [PATCH 34/51] cmd/compile: fix If lowering on loong64 + +Update #40724 + +Co-authored-by: Xiaolin Zhao +Change-Id: Ib1f2130e382191a487325a064fec5c5c9f89016c +--- + .../compile/internal/ssa/_gen/LOONG64.rules | 3 ++- + .../compile/internal/ssa/rewriteLOONG64.go | 27 +++++++++++++++++-- + 2 files changed, 27 insertions(+), 3 deletions(-) + +diff --git a/src/cmd/compile/internal/ssa/_gen/LOONG64.rules b/src/cmd/compile/internal/ssa/_gen/LOONG64.rules +index 25caad4406..c02434c53e 100644 +--- a/src/cmd/compile/internal/ssa/_gen/LOONG64.rules ++++ b/src/cmd/compile/internal/ssa/_gen/LOONG64.rules +@@ -435,7 +435,7 @@ + (GetCallerSP ...) => (LoweredGetCallerSP ...) + (GetCallerPC ...) => (LoweredGetCallerPC ...) + +-(If cond yes no) => (NE cond yes no) ++(If cond yes no) => (NE (MOVBUreg cond) yes no) + + // Write barrier. + (WB ...) => (LoweredWB ...) +@@ -469,6 +469,7 @@ + (EQ (SGTconst [0] x) yes no) => (GEZ x yes no) + (NE (SGT x (MOVVconst [0])) yes no) => (GTZ x yes no) + (EQ (SGT x (MOVVconst [0])) yes no) => (LEZ x yes no) ++(MOVBUreg x:((SGT|SGTU) _ _)) => x + + // fold offset into address + (ADDVconst [off1] (MOVVaddr [off2] {sym} ptr)) && is32Bit(off1+int64(off2)) => (MOVVaddr [int32(off1)+int32(off2)] {sym} ptr) +diff --git a/src/cmd/compile/internal/ssa/rewriteLOONG64.go b/src/cmd/compile/internal/ssa/rewriteLOONG64.go +index bb09bd2e58..a279831747 100644 +--- a/src/cmd/compile/internal/ssa/rewriteLOONG64.go ++++ b/src/cmd/compile/internal/ssa/rewriteLOONG64.go +@@ -1854,6 +1854,26 @@ func rewriteValueLOONG64_OpLOONG64MOVBUload(v *Value) bool { + } + func rewriteValueLOONG64_OpLOONG64MOVBUreg(v *Value) bool { + v_0 := v.Args[0] ++ // match: (MOVBUreg x:(SGT _ _)) ++ // result: x ++ for { ++ x := v_0 ++ if x.Op != OpLOONG64SGT { ++ break ++ } ++ v.copyOf(x) ++ return true ++ } ++ // match: (MOVBUreg x:(SGTU _ _)) ++ // result: x ++ for { ++ x := v_0 ++ if x.Op != OpLOONG64SGTU { ++ break ++ } ++ v.copyOf(x) ++ return true ++ } + // match: (MOVBUreg x:(MOVBUload _ _)) + // result: (MOVVreg x) + for { +@@ -7689,6 +7709,7 @@ func rewriteValueLOONG64_OpZero(v *Value) bool { + return false + } + func rewriteBlockLOONG64(b *Block) bool { ++ typ := &b.Func.Config.Types + switch b.Kind { + case BlockLOONG64EQ: + // match: (EQ (FPFlagTrue cmp) yes no) +@@ -7888,10 +7909,12 @@ func rewriteBlockLOONG64(b *Block) bool { + } + case BlockIf: + // match: (If cond yes no) +- // result: (NE cond yes no) ++ // result: (NE (MOVBUreg cond) yes no) + for { + cond := b.Controls[0] +- b.resetWithControl(BlockLOONG64NE, cond) ++ v0 := b.NewValue0(cond.Pos, OpLOONG64MOVBUreg, typ.UInt64) ++ v0.AddArg(cond) ++ b.resetWithControl(BlockLOONG64NE, v0) + return true + } + case BlockLOONG64LEZ: +-- +2.20.1 + diff --git a/loongarch64/0035-runtime-internal-syscall-use-ABIInternal-for-Syscall.patch b/loongarch64/0035-runtime-internal-syscall-use-ABIInternal-for-Syscall.patch new file mode 100644 index 0000000000000000000000000000000000000000..4d4872e41d3cb2a8669c7f470c35cfe2e42c3ea6 --- /dev/null +++ b/loongarch64/0035-runtime-internal-syscall-use-ABIInternal-for-Syscall.patch @@ -0,0 +1,87 @@ +From 94fddff9e1acffe0dc76248573fa65109ac1c69f Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Tue, 22 Aug 2023 19:50:03 +0800 +Subject: [PATCH 35/51] runtime/internal/syscall: use ABIInternal for Syscall6 + on loong64 + +Updates #40724 + +Co-authored-by: Xiaolin Zhao +Change-Id: I9ff50a2e5060f99826e2e8e1d99d86f9bca10e0c +--- + .../internal/syscall/asm_linux_loong64.s | 41 ++++++++++++++++++- + 1 file changed, 40 insertions(+), 1 deletion(-) + +diff --git a/src/runtime/internal/syscall/asm_linux_loong64.s b/src/runtime/internal/syscall/asm_linux_loong64.s +index d6a33f90a7..11c5bc2468 100644 +--- a/src/runtime/internal/syscall/asm_linux_loong64.s ++++ b/src/runtime/internal/syscall/asm_linux_loong64.s +@@ -5,7 +5,32 @@ + #include "textflag.h" + + // func Syscall6(num, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, errno uintptr) +-TEXT ·Syscall6(SB),NOSPLIT,$0-80 ++// ++// We need to convert to the syscall ABI. ++// ++// arg | ABIInternal | Syscall ++// --------------------------- ++// num | R4 | R11 ++// a1 | R5 | R4 ++// a2 | R6 | R5 ++// a3 | R7 | R6 ++// a4 | R8 | R7 ++// a5 | R9 | R8 ++// a6 | R10 | R9 ++// ++// r1 | R4 | R4 ++// r2 | R5 | R5 ++// err | R6 | part of R4 ++TEXT ·Syscall6(SB),NOSPLIT,$0-80 ++#ifdef GOEXPERIMENT_regabiargs ++ MOVV R4, R11 // syscall entry ++ MOVV R5, R4 ++ MOVV R6, R5 ++ MOVV R7, R6 ++ MOVV R8, R7 ++ MOVV R9, R8 ++ MOVV R10, R9 ++#else + MOVV num+0(FP), R11 // syscall entry + MOVV a1+8(FP), R4 + MOVV a2+16(FP), R5 +@@ -13,7 +38,15 @@ TEXT ·Syscall6(SB),NOSPLIT,$0-80 + MOVV a4+32(FP), R7 + MOVV a5+40(FP), R8 + MOVV a6+48(FP), R9 ++#endif + SYSCALL ++#ifdef GOEXPERIMENT_regabiargs ++ MOVV R0, R5 // r2 is not used. Always set to 0. ++ MOVW $-4096, R12 ++ BGEU R12, R4, ok ++ SUBVU R4, R0, R6 // errno ++ MOVV $-1, R4 // r1 ++#else + MOVW $-4096, R12 + BGEU R12, R4, ok + MOVV $-1, R12 +@@ -21,9 +54,15 @@ TEXT ·Syscall6(SB),NOSPLIT,$0-80 + MOVV R0, r2+64(FP) + SUBVU R4, R0, R4 + MOVV R4, errno+72(FP) ++#endif + RET + ok: ++#ifdef GOEXPERIMENT_regabiargs ++ // r1 already in R4 ++ MOVV R0, R6 // errno ++#else + MOVV R4, r1+56(FP) + MOVV R0, r2+64(FP) // r2 is not used. Always set to 0. + MOVV R0, errno+72(FP) ++#endif + RET +-- +2.20.1 + diff --git a/loongarch64/0036-cmd-compile-internal-buildcfg-enable-regABI-on-loong.patch b/loongarch64/0036-cmd-compile-internal-buildcfg-enable-regABI-on-loong.patch new file mode 100644 index 0000000000000000000000000000000000000000..21d657e2a4557ae7c62b97663ea5ab180a1008cc --- /dev/null +++ b/loongarch64/0036-cmd-compile-internal-buildcfg-enable-regABI-on-loong.patch @@ -0,0 +1,132 @@ +From 0369b323c17bdbde4f739c43001d1c1e8d45a76f Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Wed, 16 Aug 2023 10:39:38 +0800 +Subject: [PATCH 36/51] cmd/compile, internal/buildcfg: enable regABI on + loong64, and add loong64 in test func hasRegisterABI +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +goos: linux +goarch: loong64 +pkg: test/bench/go1 +cpu: Loongson-3A5000 @ 2500.00MHz + │ bench.old │ bench.new │ + │ sec/op │ sec/op vs base │ +Template 116.4m ± 1% 101.3m ± 0% -12.94% (p=0.000 n=20) +Gzip 417.2m ± 0% 419.4m ± 0% +0.53% (p=0.000 n=20) +Gunzip 87.41m ± 0% 84.61m ± 0% -3.20% (p=0.000 n=20) +FmtFprintfEmpty 97.87n ± 0% 81.05n ± 0% -17.19% (p=0.000 n=20) +FmtFprintfString 151.1n ± 0% 140.9n ± 0% -6.75% (p=0.000 n=20) +FmtFprintfInt 155.6n ± 0% 143.0n ± 0% -8.10% (p=0.000 n=20) +FmtFprintfIntInt 236.9n ± 0% 225.1n ± 0% -5.00% (p=0.000 n=20) +FmtFprintfPrefixedInt 316.8n ± 0% 331.9n ± 0% +4.77% (p=0.000 n=20) +FmtFprintfFloat 401.5n ± 0% 380.0n ± 0% -5.35% (p=0.000 n=20) +FmtManyArgs 925.3n ± 0% 910.1n ± 0% -1.64% (p=0.000 n=20) +BinaryTree17 14.04 ± 1% 12.84 ± 0% -8.52% (p=0.000 n=20) +RegexpMatchEasy0_32 133.1n ± 0% 121.3n ± 0% -8.87% (p=0.000 n=20) +RegexpMatchEasy0_1K 1.363µ ± 0% 1.337µ ± 0% -1.91% (p=0.000 n=20) +RegexpMatchEasy1_32 162.7n ± 0% 152.6n ± 0% -6.24% (p=0.000 n=20) +RegexpMatchEasy1_1K 1.505µ ± 0% 1.740µ ± 0% +15.61% (p=0.000 n=20) +RegexpMatchMedium_32 1.429µ ± 0% 1.299µ ± 0% -9.10% (p=0.000 n=20) +RegexpMatchMedium_1K 41.76µ ± 0% 38.16µ ± 0% -8.61% (p=0.000 n=20) +RegexpMatchHard_32 2.094µ ± 0% 2.157µ ± 0% +3.01% (p=0.000 n=20) +RegexpMatchHard_1K 63.25µ ± 0% 64.72µ ± 0% +2.33% (p=0.000 n=20) +JSONEncode 18.00m ± 1% 17.46m ± 1% -3.05% (p=0.000 n=20) +JSONDecode 79.49m ± 0% 72.42m ± 0% -8.89% (p=0.000 n=20) +Revcomp 1.147 ± 0% 1.255 ± 0% +9.39% (p=0.000 n=20) +Fannkuch11 3.623 ± 0% 3.410 ± 0% -5.87% (p=0.000 n=20) +Fannkuch11 3.623 ± 0% 3.410 ± 0% -5.87% (p=0.000 n=20) +GobDecode 14.26m ± 0% 12.92m ± 0% -9.36% (p=0.000 n=20) +GobEncode 16.86m ± 1% 14.96m ± 0% -11.28% (p=0.000 n=20) +GoParse 8.721m ± 0% 8.125m ± 1% -6.84% (p=0.000 n=20) +Mandelbrot200 7.203m ± 0% 7.171m ± 0% -0.44% (p=0.000 n=20) +HTTPClientServer 83.96µ ± 0% 80.83µ ± 0% -3.72% (p=0.000 n=20) +TimeParse 415.3n ± 0% 389.1n ± 0% -6.31% (p=0.000 n=20) +TimeFormat 506.4n ± 0% 495.9n ± 0% -2.06% (p=0.000 n=20) +geomean 102.6µ 98.04µ -4.40% + + │ bench.old │ bench.new │ + │ B/s │ B/s vs base │ +Template 15.90Mi ± 1% 18.26Mi ± 0% +14.88% (p=0.000 n=20) +Gzip 44.36Mi ± 0% 44.12Mi ± 0% -0.53% (p=0.000 n=20) +Gunzip 211.7Mi ± 0% 218.7Mi ± 0% +3.31% (p=0.000 n=20) +RegexpMatchEasy0_32 229.3Mi ± 0% 251.6Mi ± 0% +9.72% (p=0.000 n=20) +RegexpMatchEasy0_1K 716.4Mi ± 0% 730.3Mi ± 0% +1.94% (p=0.000 n=20) +RegexpMatchEasy1_32 187.6Mi ± 0% 200.0Mi ± 0% +6.64% (p=0.000 n=20) +RegexpMatchEasy1_1K 649.1Mi ± 0% 561.3Mi ± 0% -13.52% (p=0.000 n=20) +RegexpMatchMedium_32 21.35Mi ± 0% 23.50Mi ± 0% +10.05% (p=0.000 n=20) +RegexpMatchMedium_1K 23.38Mi ± 0% 25.59Mi ± 0% +9.42% (p=0.000 n=20) +RegexpMatchHard_32 14.57Mi ± 0% 14.14Mi ± 0% -2.95% (p=0.000 n=20) +RegexpMatchHard_1K 15.44Mi ± 0% 15.09Mi ± 0% -2.29% (p=0.000 n=20) +JSONEncode 102.8Mi ± 1% 106.0Mi ± 1% +3.15% (p=0.000 n=20) +JSONDecode 23.28Mi ± 0% 25.55Mi ± 0% +9.75% (p=0.000 n=20) +Revcomp 211.3Mi ± 0% 193.1Mi ± 0% -8.58% (p=0.000 n=20) +GobDecode 51.34Mi ± 0% 56.64Mi ± 0% +10.33% (p=0.000 n=20) +GobEncode 43.42Mi ± 1% 48.93Mi ± 0% +12.71% (p=0.000 n=20) +GoParse 6.337Mi ± 0% 6.800Mi ± 1% +7.30% (p=0.000 n=20) +geomean 61.24Mi 63.63Mi +3.91% + +Update #40724 + +Co-authored-by: Xiaolin Zhao +Change-Id: Ica823b5fbe5b95705d07e9968cb9395fb51b97e4 +--- + src/cmd/compile/internal/ssa/config.go | 4 ++-- + src/cmd/compile/internal/ssa/debug_lines_test.go | 2 +- + src/internal/buildcfg/exp.go | 4 +++- + 3 files changed, 6 insertions(+), 4 deletions(-) + +diff --git a/src/cmd/compile/internal/ssa/config.go b/src/cmd/compile/internal/ssa/config.go +index 31a6ee1af8..2d90457379 100644 +--- a/src/cmd/compile/internal/ssa/config.go ++++ b/src/cmd/compile/internal/ssa/config.go +@@ -296,8 +296,8 @@ func NewConfig(arch string, types Types, ctxt *obj.Link, optimize, softfloat boo + c.registers = registersLOONG64[:] + c.gpRegMask = gpRegMaskLOONG64 + c.fpRegMask = fpRegMaskLOONG64 +- // c.intParamRegs = paramIntRegLOONG64 +- // c.floatParamRegs = paramFloatRegLOONG64 ++ c.intParamRegs = paramIntRegLOONG64 ++ c.floatParamRegs = paramFloatRegLOONG64 + c.FPReg = framepointerRegLOONG64 + c.LinkReg = linkRegLOONG64 + c.hasGReg = true +diff --git a/src/cmd/compile/internal/ssa/debug_lines_test.go b/src/cmd/compile/internal/ssa/debug_lines_test.go +index cf115107a1..af9e2a34cf 100644 +--- a/src/cmd/compile/internal/ssa/debug_lines_test.go ++++ b/src/cmd/compile/internal/ssa/debug_lines_test.go +@@ -44,7 +44,7 @@ func testGoArch() string { + + func hasRegisterABI() bool { + switch testGoArch() { +- case "amd64", "arm64", "ppc64", "ppc64le", "riscv": ++ case "amd64", "arm64", "loong64", "ppc64", "ppc64le", "riscv": + return true + } + return false +diff --git a/src/internal/buildcfg/exp.go b/src/internal/buildcfg/exp.go +index 513070c8af..0f29233fb3 100644 +--- a/src/internal/buildcfg/exp.go ++++ b/src/internal/buildcfg/exp.go +@@ -65,6 +65,8 @@ func ParseGOEXPERIMENT(goos, goarch, goexp string) (*ExperimentFlags, error) { + case "amd64", "arm64", "ppc64le", "ppc64", "riscv64": + regabiAlwaysOn = true + regabiSupported = true ++ case "loong64": ++ regabiSupported = true + } + + baseline := goexperiment.Flags{ +@@ -129,7 +131,7 @@ func ParseGOEXPERIMENT(goos, goarch, goexp string) (*ExperimentFlags, error) { + flags.RegabiWrappers = true + flags.RegabiArgs = true + } +- // regabi is only supported on amd64, arm64, riscv64, ppc64 and ppc64le. ++ // regabi is only supported on amd64, arm64, loong64, riscv64, ppc64 and ppc64le. + if !regabiSupported { + flags.RegabiWrappers = false + flags.RegabiArgs = false +-- +2.20.1 + diff --git a/loongarch64/0037-internal-abi-internal-buildcfg-always-enable-registe.patch b/loongarch64/0037-internal-abi-internal-buildcfg-always-enable-registe.patch new file mode 100644 index 0000000000000000000000000000000000000000..cdcd54f7fcd03b16ba789882b16e5c68325ac653 --- /dev/null +++ b/loongarch64/0037-internal-abi-internal-buildcfg-always-enable-registe.patch @@ -0,0 +1,121 @@ +From 62a8dc1a42c0fdb803f84545c278edfc245c3f02 Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Wed, 30 Aug 2023 17:08:22 +0800 +Subject: [PATCH 37/51] internal/abi, internal/buildcfg: always enable register + ABI on loong64 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +goos: linux +goarch: loong64 +pkg: test/bench/go1 +cpu: Loongson-3C5000 @ 2200.00MHz + │ old.bench │ new.bench │ + │ sec/op │ sec/op vs base │ +BinaryTree17 14.48 ± 1% 12.71 ± 1% -12.19% (p=0.000 n=20) +Fannkuch11 3.873 ± 0% 4.117 ± 0% +6.28% (p=0.000 n=20) +FmtFprintfEmpty 110.00n ± 0% 91.88n ± 0% -16.47% (p=0.000 n=20) +FmtFprintfString 178.4n ± 0% 153.8n ± 0% -13.79% (p=0.000 n=20) +FmtFprintfInt 179.2n ± 0% 163.2n ± 0% -8.93% (p=0.000 n=20) +FmtFprintfIntInt 272.9n ± 0% 258.1n ± 0% -5.42% (p=0.000 n=20) +FmtFprintfPrefixedInt 382.8n ± 0% 344.1n ± 0% -10.11% (p=0.000 n=20) +FmtFprintfFloat 453.5n ± 0% 426.8n ± 0% -5.89% (p=0.000 n=20) +FmtManyArgs 1.052µ ± 0% 1.024µ ± 0% -2.71% (p=0.000 n=20) +GobDecode 15.96m ± 1% 13.77m ± 0% -13.72% (p=0.000 n=20) +GobEncode 17.95m ± 3% 15.25m ± 3% -15.03% (p=0.000 n=20) +Gzip 478.5m ± 0% 476.6m ± 0% -0.40% (p=0.000 n=20) +Gunzip 106.55m ± 0% 90.42m ± 0% -15.14% (p=0.000 n=20) +HTTPClientServer 109.4µ ± 0% 105.3µ ± 1% -3.75% (p=0.000 n=20) +JSONEncode 21.12m ± 0% 19.41m ± 0% -8.10% (p=0.000 n=20) +JSONDecode 83.09m ± 0% 77.81m ± 0% -6.35% (p=0.000 n=20) +Mandelbrot200 8.180m ± 0% 8.149m ± 0% -0.37% (p=0.000 n=20) +GoParse 9.657m ± 0% 8.913m ± 0% -7.70% (p=0.000 n=20) +RegexpMatchEasy0_32 152.4n ± 0% 136.5n ± 0% -10.43% (p=0.000 n=20) +RegexpMatchEasy0_1K 1.748µ ± 0% 1.713µ ± 0% -2.00% (p=0.000 n=20) +RegexpMatchEasy1_32 201.0n ± 0% 184.4n ± 0% -8.26% (p=0.000 n=20) +RegexpMatchEasy1_1K 1.852µ ± 0% 1.806µ ± 0% -2.48% (p=0.000 n=20) +RegexpMatchMedium_32 1.577µ ± 0% 1.525µ ± 0% -3.30% (p=0.000 n=20) +RegexpMatchMedium_1K 46.34µ ± 0% 45.22µ ± 0% -2.41% (p=0.000 n=20) +RegexpMatchHard_32 2.364µ ± 0% 2.458µ ± 0% +3.98% (p=0.000 n=20) +RegexpMatchHard_1K 71.53µ ± 0% 73.89µ ± 0% +3.30% (p=0.000 n=20) +Revcomp 1.474 ± 0% 1.308 ± 0% -11.21% (p=0.000 n=20) +Template 135.0m ± 0% 121.9m ± 0% -9.72% (p=0.000 n=20) +TimeParse 470.9n ± 0% 441.8n ± 0% -6.18% (p=0.000 n=20) +TimeFormat 584.6n ± 0% 563.3n ± 0% -3.63% (p=0.000 n=20) +geomean 118.1µ 110.3µ -6.58% + + │ old.bench │ new.bench │ + │ B/s │ B/s vs base │ +GobDecode 45.86Mi ± 1% 53.15Mi ± 0% +15.90% (p=0.000 n=20) +GobEncode 40.79Mi ± 3% 48.00Mi ± 3% +17.69% (p=0.000 n=20) +Gzip 38.68Mi ± 0% 38.83Mi ± 0% +0.41% (p=0.000 n=20) +Gunzip 173.7Mi ± 0% 204.7Mi ± 0% +17.84% (p=0.000 n=20) +JSONEncode 87.62Mi ± 0% 95.34Mi ± 0% +8.81% (p=0.000 n=20) +JSONDecode 22.27Mi ± 0% 23.78Mi ± 0% +6.79% (p=0.000 n=20) +GoParse 5.717Mi ± 0% 6.199Mi ± 0% +8.42% (p=0.000 n=20) +RegexpMatchEasy0_32 200.3Mi ± 0% 223.6Mi ± 0% +11.68% (p=0.000 n=20) +RegexpMatchEasy0_1K 558.5Mi ± 0% 570.2Mi ± 0% +2.10% (p=0.000 n=20) +RegexpMatchEasy1_32 151.8Mi ± 0% 165.5Mi ± 0% +9.02% (p=0.000 n=20) +RegexpMatchEasy1_1K 527.2Mi ± 0% 540.8Mi ± 0% +2.57% (p=0.000 n=20) +RegexpMatchMedium_32 19.35Mi ± 0% 20.02Mi ± 0% +3.45% (p=0.000 n=20) +RegexpMatchMedium_1K 21.08Mi ± 0% 21.59Mi ± 0% +2.44% (p=0.000 n=20) +RegexpMatchHard_32 12.91Mi ± 0% 12.42Mi ± 0% -3.84% (p=0.000 n=20) +RegexpMatchHard_1K 13.66Mi ± 0% 13.22Mi ± 0% -3.21% (p=0.000 n=20) +Revcomp 164.5Mi ± 0% 185.3Mi ± 0% +12.62% (p=0.000 n=20) +Template 13.71Mi ± 0% 15.19Mi ± 0% +10.78% (p=0.000 n=20) +geomean 52.97Mi 56.71Mi +7.06% + +Change-Id: I31497848e1fea6beb289a8f4d9a36795ee03253f +--- + src/internal/abi/abi_generic.go | 2 +- + src/internal/abi/abi_loong64.go | 2 -- + src/internal/buildcfg/exp.go | 4 +--- + 3 files changed, 2 insertions(+), 6 deletions(-) + +diff --git a/src/internal/abi/abi_generic.go b/src/internal/abi/abi_generic.go +index 76ef2e2898..a08d3208d4 100644 +--- a/src/internal/abi/abi_generic.go ++++ b/src/internal/abi/abi_generic.go +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build !goexperiment.regabiargs && !amd64 && !arm64 && !ppc64 && !ppc64le && !riscv64 ++//go:build !goexperiment.regabiargs && !amd64 && !arm64 && !loong64 && !ppc64 && !ppc64le && !riscv64 + + package abi + +diff --git a/src/internal/abi/abi_loong64.go b/src/internal/abi/abi_loong64.go +index c2306ae8d8..10ad89815b 100644 +--- a/src/internal/abi/abi_loong64.go ++++ b/src/internal/abi/abi_loong64.go +@@ -2,8 +2,6 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build goexperiment.regabiargs +- + package abi + + const ( +diff --git a/src/internal/buildcfg/exp.go b/src/internal/buildcfg/exp.go +index 0f29233fb3..7c7cefba7b 100644 +--- a/src/internal/buildcfg/exp.go ++++ b/src/internal/buildcfg/exp.go +@@ -62,11 +62,9 @@ func ParseGOEXPERIMENT(goos, goarch, goexp string) (*ExperimentFlags, error) { + // always on. + var regabiSupported, regabiAlwaysOn bool + switch goarch { +- case "amd64", "arm64", "ppc64le", "ppc64", "riscv64": ++ case "amd64", "arm64", "loong64", "ppc64le", "ppc64", "riscv64": + regabiAlwaysOn = true + regabiSupported = true +- case "loong64": +- regabiSupported = true + } + + baseline := goexperiment.Flags{ +-- +2.20.1 + diff --git a/loongarch64/0038-all-delete-loong64-non-register-ABI-fallback-path.patch b/loongarch64/0038-all-delete-loong64-non-register-ABI-fallback-path.patch new file mode 100644 index 0000000000000000000000000000000000000000..5922f4e8dbdfe768ecef85055d90f3c748a33e38 --- /dev/null +++ b/loongarch64/0038-all-delete-loong64-non-register-ABI-fallback-path.patch @@ -0,0 +1,493 @@ +From 44c2205ee20f4c92eb4511ca3b2be4d3db5ec2f7 Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Wed, 30 Aug 2023 17:49:55 +0800 +Subject: [PATCH 38/51] all: delete loong64 non-register ABI fallback path + +Change-Id: I6f292cbdd184c584b8a8c8af005b446be3e03a67 +--- + src/internal/bytealg/compare_loong64.s | 18 ---- + src/internal/bytealg/equal_loong64.s | 24 ----- + src/internal/bytealg/indexbyte_loong64.s | 22 ----- + src/reflect/asm_loong64.s | 10 -- + src/runtime/asm_loong64.s | 98 ------------------- + .../internal/syscall/asm_linux_loong64.s | 26 ----- + src/runtime/memclr_loong64.s | 4 - + src/runtime/memmove_loong64.s | 5 - + 8 files changed, 207 deletions(-) + +diff --git a/src/internal/bytealg/compare_loong64.s b/src/internal/bytealg/compare_loong64.s +index 311449ab18..df72a1122b 100644 +--- a/src/internal/bytealg/compare_loong64.s ++++ b/src/internal/bytealg/compare_loong64.s +@@ -6,13 +6,6 @@ + #include "textflag.h" + + TEXT ·Compare(SB),NOSPLIT,$0-56 +-#ifndef GOEXPERIMENT_regabiargs +- MOVV a_base+0(FP), R4 +- MOVV a_len+8(FP), R5 +- MOVV b_base+24(FP), R6 +- MOVV b_len+32(FP), R7 +- MOVV $ret+48(FP), R13 +-#else + // R4 = a_base + // R5 = a_len + // R6 = a_cap (unused) +@@ -21,17 +14,9 @@ TEXT ·Compare(SB),NOSPLIT,$0-56 + // R9 = b_cap (unused) + MOVV R7, R6 + MOVV R8, R7 +-#endif + JMP cmpbody<>(SB) + + TEXT runtime·cmpstring(SB),NOSPLIT,$0-40 +-#ifndef GOEXPERIMENT_regabiargs +- MOVV a_base+0(FP), R4 +- MOVV b_base+16(FP), R6 +- MOVV a_len+8(FP), R5 +- MOVV b_len+24(FP), R7 +- MOVV $ret+32(FP), R13 +-#endif + // R4 = a_base + // R5 = a_len + // R6 = b_base +@@ -100,7 +85,4 @@ samebytes: + SUBV R9, R8, R4 + + ret: +-#ifndef GOEXPERIMENT_regabiargs +- MOVV R4, (R13) +-#endif + RET +diff --git a/src/internal/bytealg/equal_loong64.s b/src/internal/bytealg/equal_loong64.s +index a3ad5c1b35..830b09bd2c 100644 +--- a/src/internal/bytealg/equal_loong64.s ++++ b/src/internal/bytealg/equal_loong64.s +@@ -9,20 +9,12 @@ + + // memequal(a, b unsafe.Pointer, size uintptr) bool + TEXT runtime·memequal(SB),NOSPLIT|NOFRAME,$0-25 +-#ifndef GOEXPERIMENT_regabiargs +- MOVV a+0(FP), R4 +- MOVV b+8(FP), R5 +- MOVV size+16(FP), R6 +-#endif + BEQ R4, R5, eq + ADDV R4, R6, R7 + PCALIGN $16 + loop: + BNE R4, R7, test + MOVV $1, R4 +-#ifndef GOEXPERIMENT_regabiargs +- MOVB R4, ret+24(FP) +-#endif + RET + test: + MOVBU (R4), R9 +@@ -32,23 +24,13 @@ test: + BEQ R9, R10, loop + + MOVB R0, R4 +-#ifndef GOEXPERIMENT_regabiargs +- MOVB R0, ret+24(FP) +-#endif + RET + eq: + MOVV $1, R4 +-#ifndef GOEXPERIMENT_regabiargs +- MOVB R4, ret+24(FP) +-#endif + RET + + // memequal_varlen(a, b unsafe.Pointer) bool + TEXT runtime·memequal_varlen(SB),NOSPLIT,$40-17 +-#ifndef GOEXPERIMENT_regabiargs +- MOVV a+0(FP), R4 +- MOVV b+8(FP), R5 +-#endif + BEQ R4, R5, eq + MOVV 8(REGCTXT), R6 // compiler stores size at offset 8 in the closure + MOVV R4, 8(R3) +@@ -56,13 +38,7 @@ TEXT runtime·memequal_varlen(SB),NOSPLIT,$40-17 + MOVV R6, 24(R3) + JAL runtime·memequal(SB) + MOVBU 32(R3), R4 +-#ifndef GOEXPERIMENT_regabiargs +- MOVB R4, ret+16(FP) +-#endif + RET + eq: + MOVV $1, R4 +-#ifndef GOEXPERIMENT_regabiargs +- MOVB R4, ret+16(FP) +-#endif + RET +diff --git a/src/internal/bytealg/indexbyte_loong64.s b/src/internal/bytealg/indexbyte_loong64.s +index 03e0660973..c9591b3cda 100644 +--- a/src/internal/bytealg/indexbyte_loong64.s ++++ b/src/internal/bytealg/indexbyte_loong64.s +@@ -6,11 +6,6 @@ + #include "textflag.h" + + TEXT ·IndexByte(SB),NOSPLIT,$0-40 +-#ifndef GOEXPERIMENT_regabiargs +- MOVV b_base+0(FP), R4 +- MOVV b_len+8(FP), R5 +- MOVBU c+24(FP), R7 // byte to find +-#endif + // R4 = b_base + // R5 = b_len + // R6 = b_cap (unused) +@@ -28,24 +23,13 @@ loop: + BNE R7, R8, loop + + SUBV R6, R4 // remove base +-#ifndef GOEXPERIMENT_regabiargs +- MOVV R4, ret+32(FP) +-#endif + RET + + notfound: + MOVV $-1, R4 +-#ifndef GOEXPERIMENT_regabiargs +- MOVV R4, ret+32(FP) +-#endif + RET + + TEXT ·IndexByteString(SB),NOSPLIT,$0-32 +-#ifndef GOEXPERIMENT_regabiargs +- MOVV s_base+0(FP), R4 +- MOVV s_len+8(FP), R5 +- MOVBU c+16(FP), R6 // byte to find +-#endif + // R4 = s_base + // R5 = s_len + // R6 = byte to find +@@ -61,14 +45,8 @@ loop: + BNE R6, R8, loop + + SUBV R7, R4 // remove base +-#ifndef GOEXPERIMENT_regabiargs +- MOVV R4, ret+24(FP) +-#endif + RET + + notfound: + MOVV $-1, R4 +-#ifndef GOEXPERIMENT_regabiargs +- MOVV R4, ret+24(FP) +-#endif + RET +diff --git a/src/reflect/asm_loong64.s b/src/reflect/asm_loong64.s +index 520f0afdd5..c0dc244497 100644 +--- a/src/reflect/asm_loong64.s ++++ b/src/reflect/asm_loong64.s +@@ -34,13 +34,8 @@ TEXT ·makeFuncStub(SB),(NOSPLIT|WRAPPER),$432 + JAL runtime·spillArgs(SB) + MOVV REGCTXT, 32(R3) // save REGCTXT > args of moveMakeFuncArgPtrs < LOCAL_REGARGS + +-#ifdef GOEXPERIMENT_regabiargs + MOVV REGCTXT, R4 + MOVV R25, R5 +-#else +- MOVV REGCTXT, 8(R3) +- MOVV R25, 16(R3) +-#endif + JAL ·moveMakeFuncArgPtrs(SB) + MOVV 32(R3), REGCTXT // restore REGCTXT + +@@ -66,13 +61,8 @@ TEXT ·methodValueCall(SB),(NOSPLIT|WRAPPER),$432 + ADDV $LOCAL_REGARGS, R3, R25 // spillArgs using R25 + JAL runtime·spillArgs(SB) + MOVV REGCTXT, 32(R3) // save REGCTXT > args of moveMakeFuncArgPtrs < LOCAL_REGARGS +-#ifdef GOEXPERIMENT_regabiargs + MOVV REGCTXT, R4 + MOVV R25, R5 +-#else +- MOVV REGCTXT, 8(R3) +- MOVV R25, 16(R3) +-#endif + JAL ·moveMakeFuncArgPtrs(SB) + MOVV 32(R3), REGCTXT // restore REGCTXT + MOVV REGCTXT, 8(R3) +diff --git a/src/runtime/asm_loong64.s b/src/runtime/asm_loong64.s +index 0a970ef20c..3c24e33cb3 100644 +--- a/src/runtime/asm_loong64.s ++++ b/src/runtime/asm_loong64.s +@@ -124,12 +124,7 @@ TEXT gogo<>(SB), NOSPLIT|NOFRAME, $0 + // Fn must never return. It should gogo(&g->sched) + // to keep running g. + TEXT runtime·mcall(SB), NOSPLIT|NOFRAME, $0-8 +-#ifdef GOEXPERIMENT_regabiargs + MOVV R4, REGCTXT +-#else +- MOVV fn+0(FP), REGCTXT +-#endif +- + // Save caller state in g->sched + MOVV R3, (g_sched+gobuf_sp)(g) + MOVV R1, (g_sched+gobuf_pc)(g) +@@ -670,7 +665,6 @@ TEXT ·checkASM(SB),NOSPLIT,$0-1 + MOVB R19, ret+0(FP) + RET + +-#ifdef GOEXPERIMENT_regabiargs + // spillArgs stores return values from registers to a *internal/abi.RegArgs in R25. + TEXT ·spillArgs(SB),NOSPLIT,$0-0 + MOVV R4, (0*8)(R25) +@@ -742,13 +736,6 @@ TEXT ·unspillArgs(SB),NOSPLIT,$0-0 + MOVD (30*8)(R25), F14 + MOVD (31*8)(R25), F15 + RET +-#else +-TEXT ·spillArgs(SB),NOSPLIT,$0-0 +- RET +- +-TEXT ·unspillArgs(SB),NOSPLIT,$0-0 +- RET +-#endif + + // gcWriteBarrier informs the GC about heap pointer writes. + // +@@ -878,155 +865,70 @@ TEXT runtime·gcWriteBarrier8(SB),NOSPLIT,$0 + // then tail call to the corresponding runtime handler. + // The tail call makes these stubs disappear in backtraces. + TEXT runtime·panicIndex(SB),NOSPLIT,$0-16 +-#ifdef GOEXPERIMENT_regabiargs + MOVV R20, R4 + MOVV R21, R5 +-#else +- MOVV R20, x+0(FP) +- MOVV R21, y+8(FP) +-#endif + JMP runtime·goPanicIndex(SB) + TEXT runtime·panicIndexU(SB),NOSPLIT,$0-16 +-#ifdef GOEXPERIMENT_regabiargs + MOVV R20, R4 + MOVV R21, R5 +-#else +- MOVV R20, x+0(FP) +- MOVV R21, y+8(FP) +-#endif + JMP runtime·goPanicIndexU(SB) + TEXT runtime·panicSliceAlen(SB),NOSPLIT,$0-16 +-#ifdef GOEXPERIMENT_regabiargs + MOVV R21, R4 + MOVV R23, R5 +-#else +- MOVV R21, x+0(FP) +- MOVV R23, y+8(FP) +-#endif + JMP runtime·goPanicSliceAlen(SB) + TEXT runtime·panicSliceAlenU(SB),NOSPLIT,$0-16 +-#ifdef GOEXPERIMENT_regabiargs + MOVV R21, R4 + MOVV R23, R5 +-#else +- MOVV R21, x+0(FP) +- MOVV R23, y+8(FP) +-#endif + JMP runtime·goPanicSliceAlenU(SB) + TEXT runtime·panicSliceAcap(SB),NOSPLIT,$0-16 +-#ifdef GOEXPERIMENT_regabiargs + MOVV R21, R4 + MOVV R23, R5 +-#else +- MOVV R21, x+0(FP) +- MOVV R23, y+8(FP) +-#endif + JMP runtime·goPanicSliceAcap(SB) + TEXT runtime·panicSliceAcapU(SB),NOSPLIT,$0-16 +-#ifdef GOEXPERIMENT_regabiargs + MOVV R21, R4 + MOVV R23, R5 +-#else +- MOVV R21, x+0(FP) +- MOVV R23, y+8(FP) +-#endif + JMP runtime·goPanicSliceAcapU(SB) + TEXT runtime·panicSliceB(SB),NOSPLIT,$0-16 +-#ifdef GOEXPERIMENT_regabiargs + MOVV R20, R4 + MOVV R21, R5 +-#else +- MOVV R20, x+0(FP) +- MOVV R21, y+8(FP) +-#endif + JMP runtime·goPanicSliceB(SB) + TEXT runtime·panicSliceBU(SB),NOSPLIT,$0-16 +-#ifdef GOEXPERIMENT_regabiargs + MOVV R20, R4 + MOVV R21, R5 +-#else +- MOVV R20, x+0(FP) +- MOVV R21, y+8(FP) +-#endif + JMP runtime·goPanicSliceBU(SB) + TEXT runtime·panicSlice3Alen(SB),NOSPLIT,$0-16 +-#ifdef GOEXPERIMENT_regabiargs + MOVV R23, R4 + MOVV R24, R5 +-#else +- MOVV R23, x+0(FP) +- MOVV R24, y+8(FP) +-#endif + JMP runtime·goPanicSlice3Alen(SB) + TEXT runtime·panicSlice3AlenU(SB),NOSPLIT,$0-16 +-#ifdef GOEXPERIMENT_regabiargs + MOVV R23, R4 + MOVV R24, R5 +-#else +- MOVV R23, x+0(FP) +- MOVV R24, y+8(FP) +-#endif + JMP runtime·goPanicSlice3AlenU(SB) + TEXT runtime·panicSlice3Acap(SB),NOSPLIT,$0-16 +-#ifdef GOEXPERIMENT_regabiargs + MOVV R23, R4 + MOVV R24, R5 +-#else +- MOVV R23, x+0(FP) +- MOVV R24, y+8(FP) +-#endif + JMP runtime·goPanicSlice3Acap(SB) + TEXT runtime·panicSlice3AcapU(SB),NOSPLIT,$0-16 +-#ifdef GOEXPERIMENT_regabiargs + MOVV R23, R4 + MOVV R24, R5 +-#else +- MOVV R23, x+0(FP) +- MOVV R24, y+8(FP) +-#endif + JMP runtime·goPanicSlice3AcapU(SB) + TEXT runtime·panicSlice3B(SB),NOSPLIT,$0-16 +-#ifdef GOEXPERIMENT_regabiargs + MOVV R21, R4 + MOVV R23, R5 +-#else +- MOVV R21, x+0(FP) +- MOVV R23, y+8(FP) +-#endif + JMP runtime·goPanicSlice3B(SB) + TEXT runtime·panicSlice3BU(SB),NOSPLIT,$0-16 +-#ifdef GOEXPERIMENT_regabiargs + MOVV R21, R4 + MOVV R23, R5 +-#else +- MOVV R21, x+0(FP) +- MOVV R23, y+8(FP) +-#endif + JMP runtime·goPanicSlice3BU(SB) + TEXT runtime·panicSlice3C(SB),NOSPLIT,$0-16 +-#ifdef GOEXPERIMENT_regabiargs + MOVV R20, R4 + MOVV R21, R5 +-#else +- MOVV R20, x+0(FP) +- MOVV R21, y+8(FP) +-#endif + JMP runtime·goPanicSlice3C(SB) + TEXT runtime·panicSlice3CU(SB),NOSPLIT,$0-16 +-#ifdef GOEXPERIMENT_regabiargs + MOVV R20, R4 + MOVV R21, R5 +-#else +- MOVV R20, x+0(FP) +- MOVV R21, y+8(FP) +-#endif + JMP runtime·goPanicSlice3CU(SB) + TEXT runtime·panicSliceConvert(SB),NOSPLIT,$0-16 +-#ifdef GOEXPERIMENT_regabiargs + MOVV R23, R4 + MOVV R24, R5 +-#else +- MOVV R23, x+0(FP) +- MOVV R24, y+8(FP) +-#endif + JMP runtime·goPanicSliceConvert(SB) +diff --git a/src/runtime/internal/syscall/asm_linux_loong64.s b/src/runtime/internal/syscall/asm_linux_loong64.s +index 11c5bc2468..ff8ad75b05 100644 +--- a/src/runtime/internal/syscall/asm_linux_loong64.s ++++ b/src/runtime/internal/syscall/asm_linux_loong64.s +@@ -22,7 +22,6 @@ + // r2 | R5 | R5 + // err | R6 | part of R4 + TEXT ·Syscall6(SB),NOSPLIT,$0-80 +-#ifdef GOEXPERIMENT_regabiargs + MOVV R4, R11 // syscall entry + MOVV R5, R4 + MOVV R6, R5 +@@ -30,39 +29,14 @@ TEXT ·Syscall6(SB),NOSPLIT,$0-80 + MOVV R8, R7 + MOVV R9, R8 + MOVV R10, R9 +-#else +- MOVV num+0(FP), R11 // syscall entry +- MOVV a1+8(FP), R4 +- MOVV a2+16(FP), R5 +- MOVV a3+24(FP), R6 +- MOVV a4+32(FP), R7 +- MOVV a5+40(FP), R8 +- MOVV a6+48(FP), R9 +-#endif + SYSCALL +-#ifdef GOEXPERIMENT_regabiargs + MOVV R0, R5 // r2 is not used. Always set to 0. + MOVW $-4096, R12 + BGEU R12, R4, ok + SUBVU R4, R0, R6 // errno + MOVV $-1, R4 // r1 +-#else +- MOVW $-4096, R12 +- BGEU R12, R4, ok +- MOVV $-1, R12 +- MOVV R12, r1+56(FP) +- MOVV R0, r2+64(FP) +- SUBVU R4, R0, R4 +- MOVV R4, errno+72(FP) +-#endif + RET + ok: +-#ifdef GOEXPERIMENT_regabiargs + // r1 already in R4 + MOVV R0, R6 // errno +-#else +- MOVV R4, r1+56(FP) +- MOVV R0, r2+64(FP) // r2 is not used. Always set to 0. +- MOVV R0, errno+72(FP) +-#endif + RET +diff --git a/src/runtime/memclr_loong64.s b/src/runtime/memclr_loong64.s +index 313e4d4f33..1d45e82d49 100644 +--- a/src/runtime/memclr_loong64.s ++++ b/src/runtime/memclr_loong64.s +@@ -7,10 +7,6 @@ + + // func memclrNoHeapPointers(ptr unsafe.Pointer, n uintptr) + TEXT runtime·memclrNoHeapPointers(SB),NOSPLIT,$0-16 +-#ifndef GOEXPERIMENT_regabiargs +- MOVV ptr+0(FP), R4 +- MOVV n+8(FP), R5 +-#endif + ADDV R4, R5, R6 + + // if less than 8 bytes, do one byte at a time +diff --git a/src/runtime/memmove_loong64.s b/src/runtime/memmove_loong64.s +index 5b7aeba698..a94cf999bc 100644 +--- a/src/runtime/memmove_loong64.s ++++ b/src/runtime/memmove_loong64.s +@@ -8,11 +8,6 @@ + + // func memmove(to, from unsafe.Pointer, n uintptr) + TEXT runtime·memmove(SB), NOSPLIT|NOFRAME, $0-24 +-#ifndef GOEXPERIMENT_regabiargs +- MOVV to+0(FP), R4 +- MOVV from+8(FP), R5 +- MOVV n+16(FP), R6 +-#endif + BNE R6, check + RET + +-- +2.20.1 + diff --git a/loongarch64/0039-cmd-internal-obj-loong64-using-LookupABI-to-find-duf.patch b/loongarch64/0039-cmd-internal-obj-loong64-using-LookupABI-to-find-duf.patch new file mode 100644 index 0000000000000000000000000000000000000000..f02a1d425da7b2239f9ec4dde7256f23e2a0d2b6 --- /dev/null +++ b/loongarch64/0039-cmd-internal-obj-loong64-using-LookupABI-to-find-duf.patch @@ -0,0 +1,33 @@ +From c58321dd268f8f941a50901fa2be80a462e7c8a5 Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Sun, 8 Oct 2023 08:36:19 +0800 +Subject: [PATCH 39/51] cmd/internal/obj/loong64: using LookupABI to find + duff{copy,zero} when rewriting GOT + +Because register-passing parameters have been enabled, using Lookup +to find duffcopy and duffzero fails and returns incorrect values. + +Change-Id: I67ddec30c4a61ec1a0c7f7c27df682c0b5c36068 +--- + src/cmd/internal/obj/loong64/obj.go | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/cmd/internal/obj/loong64/obj.go b/src/cmd/internal/obj/loong64/obj.go +index ed5165418d..f1850f1caa 100644 +--- a/src/cmd/internal/obj/loong64/obj.go ++++ b/src/cmd/internal/obj/loong64/obj.go +@@ -100,9 +100,9 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) { + if p.As == obj.ADUFFCOPY || p.As == obj.ADUFFZERO { + var sym *obj.LSym + if p.As == obj.ADUFFZERO { +- sym = ctxt.Lookup("runtime.duffzero") ++ sym = ctxt.LookupABI("runtime.duffzero", obj.ABIInternal) + } else { +- sym = ctxt.Lookup("runtime.duffcopy") ++ sym = ctxt.LookupABI("runtime.duffcopy", obj.ABIInternal) + } + offset := p.To.Offset + p.As = AMOVV +-- +2.20.1 + diff --git a/loongarch64/0040-cmd-internal-cmd-link-unify-the-relocation-naming-st.patch b/loongarch64/0040-cmd-internal-cmd-link-unify-the-relocation-naming-st.patch new file mode 100644 index 0000000000000000000000000000000000000000..ac4234cc332aa96bcbe0f03db500382af7adf1e1 --- /dev/null +++ b/loongarch64/0040-cmd-internal-cmd-link-unify-the-relocation-naming-st.patch @@ -0,0 +1,404 @@ +From e7c4d60d2d82c4ab37c12b012bfc35973c5bd7fb Mon Sep 17 00:00:00 2001 +From: limeidan +Date: Wed, 11 Oct 2023 18:01:59 +0800 +Subject: [PATCH 40/51] cmd/internal, cmd/link: unify the relocation naming + style of loong64 + +Change-Id: Ica24a7c351b26a4375bbc52b719c69b78e89c5df +--- + src/cmd/internal/obj/loong64/asm.go | 30 +++++------ + src/cmd/internal/objabi/reloctype.go | 28 +++++------ + src/cmd/internal/objabi/reloctype_string.go | 18 +++---- + src/cmd/link/internal/loong64/asm.go | 56 ++++++++++----------- + 4 files changed, 65 insertions(+), 67 deletions(-) + +diff --git a/src/cmd/internal/obj/loong64/asm.go b/src/cmd/internal/obj/loong64/asm.go +index 74ee2b6cea..0034f7bdb9 100644 +--- a/src/cmd/internal/obj/loong64/asm.go ++++ b/src/cmd/internal/obj/loong64/asm.go +@@ -1677,7 +1677,7 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) { + rel.Siz = 4 + rel.Sym = p.To.Sym + rel.Add = p.To.Offset +- rel.Type = objabi.R_ADDRLOONG64U ++ rel.Type = objabi.R_LOONG64_ADDR_HI + + o2 = OP_12IRR(c.opirr(p.As), uint32(0), uint32(REGTMP), uint32(p.From.Reg)) + rel2 := obj.Addrel(c.cursym) +@@ -1685,7 +1685,7 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) { + rel2.Siz = 4 + rel2.Sym = p.To.Sym + rel2.Add = p.To.Offset +- rel2.Type = objabi.R_ADDRLOONG64 ++ rel2.Type = objabi.R_LOONG64_ADDR_LO + + case 51: // mov addr,r ==> pcalau12i + lw + o1 = OP_IR(c.opir(APCALAU12I), uint32(0), uint32(REGTMP)) +@@ -1694,14 +1694,14 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) { + rel.Siz = 4 + rel.Sym = p.From.Sym + rel.Add = p.From.Offset +- rel.Type = objabi.R_ADDRLOONG64U ++ rel.Type = objabi.R_LOONG64_ADDR_HI + o2 = OP_12IRR(c.opirr(-p.As), uint32(0), uint32(REGTMP), uint32(p.To.Reg)) + rel2 := obj.Addrel(c.cursym) + rel2.Off = int32(c.pc + 4) + rel2.Siz = 4 + rel2.Sym = p.From.Sym + rel2.Add = p.From.Offset +- rel2.Type = objabi.R_ADDRLOONG64 ++ rel2.Type = objabi.R_LOONG64_ADDR_LO + + case 52: // mov $lext, r + // NOTE: this case does not use REGTMP. If it ever does, +@@ -1712,14 +1712,14 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) { + rel.Siz = 4 + rel.Sym = p.From.Sym + rel.Add = p.From.Offset +- rel.Type = objabi.R_ADDRLOONG64U ++ rel.Type = objabi.R_LOONG64_ADDR_HI + o2 = OP_12IRR(c.opirr(add), uint32(0), uint32(p.To.Reg), uint32(p.To.Reg)) + rel2 := obj.Addrel(c.cursym) + rel2.Off = int32(c.pc + 4) + rel2.Siz = 4 + rel2.Sym = p.From.Sym + rel2.Add = p.From.Offset +- rel2.Type = objabi.R_ADDRLOONG64 ++ rel2.Type = objabi.R_LOONG64_ADDR_LO + + case 53: // mov r, tlsvar ==> lu12i.w + ori + add r2, regtmp + sw o(regtmp) + // NOTE: this case does not use REGTMP. If it ever does, +@@ -1730,14 +1730,14 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) { + rel.Siz = 4 + rel.Sym = p.To.Sym + rel.Add = p.To.Offset +- rel.Type = objabi.R_ADDRLOONG64TLSU ++ rel.Type = objabi.R_LOONG64_TLS_LE_HI + o2 = OP_12IRR(c.opirr(AOR), uint32(0), uint32(REGTMP), uint32(REGTMP)) + rel2 := obj.Addrel(c.cursym) + rel2.Off = int32(c.pc + 4) + rel2.Siz = 4 + rel2.Sym = p.To.Sym + rel2.Add = p.To.Offset +- rel2.Type = objabi.R_ADDRLOONG64TLS ++ rel2.Type = objabi.R_LOONG64_TLS_LE_LO + o3 = OP_RRR(c.oprrr(AADDV), uint32(REG_R2), uint32(REGTMP), uint32(REGTMP)) + o4 = OP_12IRR(c.opirr(p.As), uint32(0), uint32(REGTMP), uint32(p.From.Reg)) + +@@ -1750,14 +1750,14 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) { + rel.Siz = 4 + rel.Sym = p.From.Sym + rel.Add = p.From.Offset +- rel.Type = objabi.R_ADDRLOONG64TLSU ++ rel.Type = objabi.R_LOONG64_TLS_LE_HI + o2 = OP_12IRR(c.opirr(AOR), uint32(0), uint32(REGTMP), uint32(REGTMP)) + rel2 := obj.Addrel(c.cursym) + rel2.Off = int32(c.pc + 4) + rel2.Siz = 4 + rel2.Sym = p.From.Sym + rel2.Add = p.From.Offset +- rel2.Type = objabi.R_ADDRLOONG64TLS ++ rel2.Type = objabi.R_LOONG64_TLS_LE_LO + o3 = OP_RRR(c.oprrr(AADDV), uint32(REG_R2), uint32(REGTMP), uint32(REGTMP)) + o4 = OP_12IRR(c.opirr(-p.As), uint32(0), uint32(REGTMP), uint32(p.To.Reg)) + +@@ -1770,14 +1770,14 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) { + rel.Siz = 4 + rel.Sym = p.From.Sym + rel.Add = p.From.Offset +- rel.Type = objabi.R_ADDRLOONG64TLSU ++ rel.Type = objabi.R_LOONG64_TLS_LE_HI + o2 = OP_12IRR(c.opirr(AOR), uint32(0), uint32(REGTMP), uint32(REGTMP)) + rel2 := obj.Addrel(c.cursym) + rel2.Off = int32(c.pc + 4) + rel2.Siz = 4 + rel2.Sym = p.From.Sym + rel2.Add = p.From.Offset +- rel2.Type = objabi.R_ADDRLOONG64TLS ++ rel2.Type = objabi.R_LOONG64_TLS_LE_LO + o3 = OP_RRR(c.oprrr(AADDV), uint32(REG_R2), uint32(REGTMP), uint32(p.To.Reg)) + + case 56: // mov r, tlsvar IE model ==> (pcalau12i + ld.d)tlsvar@got + add.d + st.d +@@ -1787,7 +1787,7 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) { + rel.Siz = 4 + rel.Sym = p.To.Sym + rel.Add = 0x0 +- rel.Type = objabi.R_LOONG64_TLS_IE_PCREL_HI ++ rel.Type = objabi.R_LOONG64_TLS_IE_HI + o2 = OP_12IRR(c.opirr(-p.As), uint32(0), uint32(REGTMP), uint32(REGTMP)) + rel2 := obj.Addrel(c.cursym) + rel2.Off = int32(c.pc + 4) +@@ -1805,7 +1805,7 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) { + rel.Siz = 4 + rel.Sym = p.From.Sym + rel.Add = 0x0 +- rel.Type = objabi.R_LOONG64_TLS_IE_PCREL_HI ++ rel.Type = objabi.R_LOONG64_TLS_IE_HI + o2 = OP_12IRR(c.opirr(-p.As), uint32(0), uint32(REGTMP), uint32(REGTMP)) + rel2 := obj.Addrel(c.cursym) + rel2.Off = int32(c.pc + 4) +@@ -1858,7 +1858,7 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) { + rel.Off = int32(c.pc) + rel.Siz = 4 + rel.Sym = p.From.Sym +- rel.Type = objabi.R_LOONG64_GOTPCREL_HI ++ rel.Type = objabi.R_LOONG64_GOT_HI + rel.Add = 0x0 + o2 = OP_12IRR(c.opirr(-p.As), uint32(0), uint32(p.To.Reg), uint32(p.To.Reg)) + rel2 := obj.Addrel(c.cursym) +diff --git a/src/cmd/internal/objabi/reloctype.go b/src/cmd/internal/objabi/reloctype.go +index 241a79817c..b1934e424f 100644 +--- a/src/cmd/internal/objabi/reloctype.go ++++ b/src/cmd/internal/objabi/reloctype.go +@@ -291,34 +291,32 @@ const ( + + // Loong64. + +- // R_ADDRLOONG64 resolves to the low 12 bits of an external address, by encoding +- // it into the instruction. +- R_ADDRLOONG64 +- +- // R_ADDRLOONG64U resolves to the sign-adjusted "upper" 20 bits (bit 5-24) of an ++ // R_LOONG64_ADDR_HI resolves to the sign-adjusted "upper" 20 bits (bit 5-24) of an + // external address, by encoding it into the instruction. +- R_ADDRLOONG64U ++ // R_LOONG64_ADDR_LO resolves to the low 12 bits of an external address, by encoding ++ // it into the instruction. ++ R_LOONG64_ADDR_HI ++ R_LOONG64_ADDR_LO + +- // R_ADDRLOONG64TLS resolves to the low 12 bits of a TLS address (offset from ++ // R_LOONG64_TLS_LE_HI resolves to the high 20 bits of a TLS address (offset from + // thread pointer), by encoding it into the instruction. +- R_ADDRLOONG64TLS +- +- // R_ADDRLOONG64TLSU resolves to the high 20 bits of a TLS address (offset from ++ // R_LOONG64_TLS_LE_LO resolves to the low 12 bits of a TLS address (offset from + // thread pointer), by encoding it into the instruction. +- R_ADDRLOONG64TLSU ++ R_LOONG64_TLS_LE_HI ++ R_LOONG64_TLS_LE_LO + + // R_CALLLOONG64 resolves to non-PC-relative target address of a CALL (BL/JIRL) + // instruction, by encoding the address into the instruction. + R_CALLLOONG64 + +- // R_LOONG64_TLS_IE_PCREL_HI and R_LOONG64_TLS_IE_LO relocates a pcalau12i, ld.d ++ // R_LOONG64_TLS_IE_HI and R_LOONG64_TLS_IE_LO relocates a pcalau12i, ld.d + // pair to compute the address of the GOT slot of the tls symbol. +- R_LOONG64_TLS_IE_PCREL_HI ++ R_LOONG64_TLS_IE_HI + R_LOONG64_TLS_IE_LO + +- // R_LOONG64_GOTPCREL_HI and R_LOONG64_GOT_LO relocates an pcalau12i, ld.d pair to compute ++ // R_LOONG64_GOT_HI and R_LOONG64_GOT_LO relocates an pcalau12i, ld.d pair to compute + // the address of the GOT slot of the referenced symbol. +- R_LOONG64_GOTPCREL_HI ++ R_LOONG64_GOT_HI + R_LOONG64_GOT_LO + + // R_JMPLOONG64 resolves to non-PC-relative target address of a JMP instruction, +diff --git a/src/cmd/internal/objabi/reloctype_string.go b/src/cmd/internal/objabi/reloctype_string.go +index e0649a5b0a..3e61c77dc0 100644 +--- a/src/cmd/internal/objabi/reloctype_string.go ++++ b/src/cmd/internal/objabi/reloctype_string.go +@@ -1,4 +1,4 @@ +-// Code generated by "stringer -type=RelocType"; DO NOT EDIT. ++// Code generated by "stringer -type=RelocType cmd/internal/objabi/reloctype.go"; DO NOT EDIT. + + package objabi + +@@ -74,14 +74,14 @@ func _() { + _ = x[R_RISCV_TLS_IE_ITYPE-64] + _ = x[R_RISCV_TLS_IE_STYPE-65] + _ = x[R_PCRELDBL-66] +- _ = x[R_ADDRLOONG64-67] +- _ = x[R_ADDRLOONG64U-68] +- _ = x[R_ADDRLOONG64TLS-69] +- _ = x[R_ADDRLOONG64TLSU-70] ++ _ = x[R_LOONG64_ADDR_HI-67] ++ _ = x[R_LOONG64_ADDR_LO-68] ++ _ = x[R_LOONG64_TLS_LE_HI-69] ++ _ = x[R_LOONG64_TLS_LE_LO-70] + _ = x[R_CALLLOONG64-71] +- _ = x[R_LOONG64_TLS_IE_PCREL_HI-72] ++ _ = x[R_LOONG64_TLS_IE_HI-72] + _ = x[R_LOONG64_TLS_IE_LO-73] +- _ = x[R_LOONG64_GOTPCREL_HI-74] ++ _ = x[R_LOONG64_GOT_HI-74] + _ = x[R_LOONG64_GOT_LO-75] + _ = x[R_JMPLOONG64-76] + _ = x[R_ADDRMIPSU-77] +@@ -93,9 +93,9 @@ func _() { + _ = x[R_INITORDER-83] + } + +-const _RelocType_name = "R_ADDRR_ADDRPOWERR_ADDRARM64R_ADDRMIPSR_ADDROFFR_SIZER_CALLR_CALLARMR_CALLARM64R_CALLINDR_CALLPOWERR_CALLMIPSR_CONSTR_PCRELR_TLS_LER_TLS_IER_GOTOFFR_PLT0R_PLT1R_PLT2R_USEFIELDR_USETYPER_USEIFACER_USEIFACEMETHODR_USEGENERICIFACEMETHODR_METHODOFFR_KEEPR_POWER_TOCR_GOTPCRELR_JMPMIPSR_DWARFSECREFR_DWARFFILEREFR_ARM64_TLS_LER_ARM64_TLS_IER_ARM64_GOTPCRELR_ARM64_GOTR_ARM64_PCRELR_ARM64_PCREL_LDST8R_ARM64_PCREL_LDST16R_ARM64_PCREL_LDST32R_ARM64_PCREL_LDST64R_ARM64_LDST8R_ARM64_LDST16R_ARM64_LDST32R_ARM64_LDST64R_ARM64_LDST128R_POWER_TLS_LER_POWER_TLS_IER_POWER_TLSR_POWER_TLS_IE_PCREL34R_POWER_TLS_LE_TPREL34R_ADDRPOWER_DSR_ADDRPOWER_GOTR_ADDRPOWER_GOT_PCREL34R_ADDRPOWER_PCRELR_ADDRPOWER_TOCRELR_ADDRPOWER_TOCREL_DSR_ADDRPOWER_D34R_ADDRPOWER_PCREL34R_RISCV_CALLR_RISCV_CALL_TRAMPR_RISCV_PCREL_ITYPER_RISCV_PCREL_STYPER_RISCV_TLS_IE_ITYPER_RISCV_TLS_IE_STYPER_PCRELDBLR_ADDRLOONG64R_ADDRLOONG64UR_ADDRLOONG64TLSR_ADDRLOONG64TLSUR_CALLLOONG64R_LOONG64_TLS_IE_PCREL_HIR_LOONG64_TLS_IE_LOR_LOONG64_GOTPCREL_HIR_LOONG64_GOT_LOR_JMPLOONG64R_ADDRMIPSUR_ADDRMIPSTLSR_ADDRCUOFFR_WASMIMPORTR_XCOFFREFR_PEIMAGEOFFR_INITORDER" ++const _RelocType_name = "R_ADDRR_ADDRPOWERR_ADDRARM64R_ADDRMIPSR_ADDROFFR_SIZER_CALLR_CALLARMR_CALLARM64R_CALLINDR_CALLPOWERR_CALLMIPSR_CONSTR_PCRELR_TLS_LER_TLS_IER_GOTOFFR_PLT0R_PLT1R_PLT2R_USEFIELDR_USETYPER_USEIFACER_USEIFACEMETHODR_USEGENERICIFACEMETHODR_METHODOFFR_KEEPR_POWER_TOCR_GOTPCRELR_JMPMIPSR_DWARFSECREFR_DWARFFILEREFR_ARM64_TLS_LER_ARM64_TLS_IER_ARM64_GOTPCRELR_ARM64_GOTR_ARM64_PCRELR_ARM64_PCREL_LDST8R_ARM64_PCREL_LDST16R_ARM64_PCREL_LDST32R_ARM64_PCREL_LDST64R_ARM64_LDST8R_ARM64_LDST16R_ARM64_LDST32R_ARM64_LDST64R_ARM64_LDST128R_POWER_TLS_LER_POWER_TLS_IER_POWER_TLSR_POWER_TLS_IE_PCREL34R_POWER_TLS_LE_TPREL34R_ADDRPOWER_DSR_ADDRPOWER_GOTR_ADDRPOWER_GOT_PCREL34R_ADDRPOWER_PCRELR_ADDRPOWER_TOCRELR_ADDRPOWER_TOCREL_DSR_ADDRPOWER_D34R_ADDRPOWER_PCREL34R_RISCV_CALLR_RISCV_CALL_TRAMPR_RISCV_PCREL_ITYPER_RISCV_PCREL_STYPER_RISCV_TLS_IE_ITYPER_RISCV_TLS_IE_STYPER_PCRELDBLR_LOONG64_ADDR_HIR_LOONG64_ADDR_LOR_LOONG64_TLS_LE_HIR_LOONG64_TLS_LE_LOR_CALLLOONG64R_LOONG64_TLS_IE_HIR_LOONG64_TLS_IE_LOR_LOONG64_GOT_HIR_LOONG64_GOT_LOR_JMPLOONG64R_ADDRMIPSUR_ADDRMIPSTLSR_ADDRCUOFFR_WASMIMPORTR_XCOFFREFR_PEIMAGEOFFR_INITORDER" + +-var _RelocType_index = [...]uint16{0, 6, 17, 28, 38, 47, 53, 59, 68, 79, 88, 99, 109, 116, 123, 131, 139, 147, 153, 159, 165, 175, 184, 194, 210, 233, 244, 250, 261, 271, 280, 293, 307, 321, 335, 351, 362, 375, 394, 414, 434, 454, 467, 481, 495, 509, 524, 538, 552, 563, 585, 607, 621, 636, 659, 676, 694, 715, 730, 749, 761, 779, 798, 817, 837, 857, 867, 880, 894, 910, 927, 940, 965, 984, 1005, 1021, 1033, 1044, 1057, 1068, 1080, 1090, 1102, 1113} ++var _RelocType_index = [...]uint16{0, 6, 17, 28, 38, 47, 53, 59, 68, 79, 88, 99, 109, 116, 123, 131, 139, 147, 153, 159, 165, 175, 184, 194, 210, 233, 244, 250, 261, 271, 280, 293, 307, 321, 335, 351, 362, 375, 394, 414, 434, 454, 467, 481, 495, 509, 524, 538, 552, 563, 585, 607, 621, 636, 659, 676, 694, 715, 730, 749, 761, 779, 798, 817, 837, 857, 867, 884, 901, 920, 939, 952, 971, 990, 1006, 1022, 1034, 1045, 1058, 1069, 1081, 1091, 1103, 1114} + + func (i RelocType) String() string { + i -= 1 +diff --git a/src/cmd/link/internal/loong64/asm.go b/src/cmd/link/internal/loong64/asm.go +index d1296c3309..99b568cfbb 100644 +--- a/src/cmd/link/internal/loong64/asm.go ++++ b/src/cmd/link/internal/loong64/asm.go +@@ -34,7 +34,7 @@ func gentext(ctxt *ld.Link, ldr *loader.Loader) { + // 0: 1a000004 pcalau12i $a0, 0 + // 0: R_LARCH_PCALA_HI20 local.moduledata + o(0x1a000004) +- rel, _ := initfunc.AddRel(objabi.R_ADDRLOONG64U) ++ rel, _ := initfunc.AddRel(objabi.R_LOONG64_ADDR_HI) + rel.SetOff(0) + rel.SetSiz(4) + rel.SetSym(ctxt.Moduledata) +@@ -42,7 +42,7 @@ func gentext(ctxt *ld.Link, ldr *loader.Loader) { + // 4: 02c00084 addi.d $a0, $a0, 0 + // 4: R_LARCH_PCALA_LO12 local.moduledata + o(0x02c00084) +- rel2, _ := initfunc.AddRel(objabi.R_ADDRLOONG64) ++ rel2, _ := initfunc.AddRel(objabi.R_LOONG64_ADDR_LO) + rel2.SetOff(4) + rel2.SetSiz(4) + rel2.SetSym(ctxt.Moduledata) +@@ -84,12 +84,12 @@ func elfreloc1(ctxt *ld.Link, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym, + default: + return false + } +- case objabi.R_ADDRLOONG64TLS: ++ case objabi.R_LOONG64_TLS_LE_LO: + out.Write64(uint64(sectoff)) + out.Write64(uint64(elf.R_LARCH_TLS_LE_LO12) | uint64(elfsym)<<32) + out.Write64(uint64(r.Xadd)) + +- case objabi.R_ADDRLOONG64TLSU: ++ case objabi.R_LOONG64_TLS_LE_HI: + out.Write64(uint64(sectoff)) + out.Write64(uint64(elf.R_LARCH_TLS_LE_HI20) | uint64(elfsym)<<32) + out.Write64(uint64(r.Xadd)) +@@ -99,7 +99,7 @@ func elfreloc1(ctxt *ld.Link, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym, + out.Write64(uint64(elf.R_LARCH_B26) | uint64(elfsym)<<32) + out.Write64(uint64(r.Xadd)) + +- case objabi.R_LOONG64_TLS_IE_PCREL_HI: ++ case objabi.R_LOONG64_TLS_IE_HI: + out.Write64(uint64(sectoff)) + out.Write64(uint64(elf.R_LARCH_TLS_IE_PC_HI20) | uint64(elfsym)<<32) + out.Write64(uint64(0x0)) +@@ -109,17 +109,17 @@ func elfreloc1(ctxt *ld.Link, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym, + out.Write64(uint64(elf.R_LARCH_TLS_IE_PC_LO12) | uint64(elfsym)<<32) + out.Write64(uint64(0x0)) + +- case objabi.R_ADDRLOONG64: ++ case objabi.R_LOONG64_ADDR_LO: + out.Write64(uint64(sectoff)) + out.Write64(uint64(elf.R_LARCH_PCALA_LO12) | uint64(elfsym)<<32) + out.Write64(uint64(r.Xadd)) + +- case objabi.R_ADDRLOONG64U: ++ case objabi.R_LOONG64_ADDR_HI: + out.Write64(uint64(sectoff)) + out.Write64(uint64(elf.R_LARCH_PCALA_HI20) | uint64(elfsym)<<32) + out.Write64(uint64(r.Xadd)) + +- case objabi.R_LOONG64_GOTPCREL_HI: ++ case objabi.R_LOONG64_GOT_HI: + out.Write64(uint64(sectoff)) + out.Write64(uint64(elf.R_LARCH_GOT_PC_HI20) | uint64(elfsym)<<32) + out.Write64(uint64(0x0)) +@@ -147,10 +147,10 @@ func archreloc(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loade + switch r.Type() { + default: + return val, 0, false +- case objabi.R_ADDRLOONG64, +- objabi.R_LOONG64_GOTPCREL_HI, +- objabi.R_LOONG64_GOT_LO, +- objabi.R_ADDRLOONG64U: ++ case objabi.R_LOONG64_ADDR_HI, ++ objabi.R_LOONG64_ADDR_LO, ++ objabi.R_LOONG64_GOT_HI, ++ objabi.R_LOONG64_GOT_LO: + // set up addend for eventual relocation via outer symbol. + rs, _ := ld.FoldSubSymbolOffset(ldr, rs) + rst := ldr.SymType(rs) +@@ -158,11 +158,11 @@ func archreloc(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loade + ldr.Errorf(s, "missing section for %s", ldr.SymName(rs)) + } + return val, 1, true +- case objabi.R_ADDRLOONG64TLS, +- objabi.R_ADDRLOONG64TLSU, ++ case objabi.R_LOONG64_TLS_LE_HI, ++ objabi.R_LOONG64_TLS_LE_LO, + objabi.R_CALLLOONG64, + objabi.R_JMPLOONG64, +- objabi.R_LOONG64_TLS_IE_PCREL_HI, ++ objabi.R_LOONG64_TLS_IE_HI, + objabi.R_LOONG64_TLS_IE_LO: + return val, 1, true + } +@@ -176,18 +176,18 @@ func archreloc(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loade + return r.Add(), noExtReloc, isOk + case objabi.R_GOTOFF: + return ldr.SymValue(r.Sym()) + r.Add() - ldr.SymValue(syms.GOT), noExtReloc, isOk +- case objabi.R_ADDRLOONG64, +- objabi.R_ADDRLOONG64U: ++ case objabi.R_LOONG64_ADDR_HI, ++ objabi.R_LOONG64_ADDR_LO: + pc := ldr.SymValue(s) + int64(r.Off()) + t := calculatePCAlignedReloc(r.Type(), ldr.SymAddr(rs)+r.Add(), pc) +- if r.Type() == objabi.R_ADDRLOONG64 { ++ if r.Type() == objabi.R_LOONG64_ADDR_LO { + return int64(val&0xffc003ff | (t << 10)), noExtReloc, isOk + } + return int64(val&0xfe00001f | (t << 5)), noExtReloc, isOk +- case objabi.R_ADDRLOONG64TLS, +- objabi.R_ADDRLOONG64TLSU: ++ case objabi.R_LOONG64_TLS_LE_HI, ++ objabi.R_LOONG64_TLS_LE_LO: + t := ldr.SymAddr(rs) + r.Add() +- if r.Type() == objabi.R_ADDRLOONG64TLS { ++ if r.Type() == objabi.R_LOONG64_TLS_LE_LO { + return int64(val&0xffc003ff | ((t & 0xfff) << 10)), noExtReloc, isOk + } + return int64(val&0xfe00001f | (((t) >> 12 << 5) & 0x1ffffe0)), noExtReloc, isOk +@@ -207,20 +207,20 @@ func archrelocvariant(*ld.Target, *loader.Loader, loader.Reloc, sym.RelocVariant + + func extreloc(target *ld.Target, ldr *loader.Loader, r loader.Reloc, s loader.Sym) (loader.ExtReloc, bool) { + switch r.Type() { +- case objabi.R_ADDRLOONG64, +- objabi.R_ADDRLOONG64U, +- objabi.R_LOONG64_GOTPCREL_HI, ++ case objabi.R_LOONG64_ADDR_HI, ++ objabi.R_LOONG64_ADDR_LO, ++ objabi.R_LOONG64_GOT_HI, + objabi.R_LOONG64_GOT_LO: + + return ld.ExtrelocViaOuterSym(ldr, r, s), true + +- case objabi.R_ADDRLOONG64TLS, +- objabi.R_ADDRLOONG64TLSU, ++ case objabi.R_LOONG64_TLS_LE_HI, ++ objabi.R_LOONG64_TLS_LE_LO, + objabi.R_CONST, + objabi.R_GOTOFF, + objabi.R_CALLLOONG64, + objabi.R_JMPLOONG64, +- objabi.R_LOONG64_TLS_IE_PCREL_HI, ++ objabi.R_LOONG64_TLS_IE_HI, + objabi.R_LOONG64_TLS_IE_LO: + return ld.ExtrelocSimple(ldr, r), true + } +@@ -229,7 +229,7 @@ func extreloc(target *ld.Target, ldr *loader.Loader, r loader.Reloc, s loader.Sy + + func isRequestingLowPageBits(t objabi.RelocType) bool { + switch t { +- case objabi.R_ADDRLOONG64: ++ case objabi.R_LOONG64_ADDR_LO: + return true + } + return false +-- +2.20.1 + diff --git a/loongarch64/0041-cmd-link-internal-loadelf-remove-useless-relocation-.patch b/loongarch64/0041-cmd-link-internal-loadelf-remove-useless-relocation-.patch new file mode 100644 index 0000000000000000000000000000000000000000..7acea20dea71565cee2dc09d60072c109d06c137 --- /dev/null +++ b/loongarch64/0041-cmd-link-internal-loadelf-remove-useless-relocation-.patch @@ -0,0 +1,31 @@ +From 74ea55ce2a58ce529d268f65fa7184e6b6ba4482 Mon Sep 17 00:00:00 2001 +From: limeidan +Date: Tue, 24 Oct 2023 19:50:32 +0800 +Subject: [PATCH 41/51] cmd/link/internal/loadelf: remove useless relocation + size information of loong64 + +Change-Id: I86de74df2b6a205b454e3fee55607dcf28fb4a5f +--- + src/cmd/link/internal/loadelf/ldelf.go | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +diff --git a/src/cmd/link/internal/loadelf/ldelf.go b/src/cmd/link/internal/loadelf/ldelf.go +index 5ab7cf2204..1dc6a3f1f3 100644 +--- a/src/cmd/link/internal/loadelf/ldelf.go ++++ b/src/cmd/link/internal/loadelf/ldelf.go +@@ -1007,11 +1007,7 @@ func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, uint8, error) { + MIPS64 | uint32(elf.R_MIPS_GOT_DISP)<<16: + return 4, 4, nil + +- case LOONG64 | uint32(elf.R_LARCH_SOP_PUSH_PCREL)<<16, +- LOONG64 | uint32(elf.R_LARCH_SOP_PUSH_GPREL)<<16, +- LOONG64 | uint32(elf.R_LARCH_SOP_PUSH_ABSOLUTE)<<16, +- LOONG64 | uint32(elf.R_LARCH_MARK_LA)<<16, +- LOONG64 | uint32(elf.R_LARCH_SOP_POP_32_S_0_10_10_16_S2)<<16, ++ case LOONG64 | uint32(elf.R_LARCH_MARK_LA)<<16, + LOONG64 | uint32(elf.R_LARCH_MARK_PCREL)<<16, + LOONG64 | uint32(elf.R_LARCH_32_PCREL)<<16: + return 4, 4, nil +-- +2.20.1 + diff --git a/loongarch64/0042-cmd-link-internal-loadelf-add-additional-relocations.patch b/loongarch64/0042-cmd-link-internal-loadelf-add-additional-relocations.patch new file mode 100644 index 0000000000000000000000000000000000000000..2af5604d7288229be1dcd5a7b0120d53d3b47d8a --- /dev/null +++ b/loongarch64/0042-cmd-link-internal-loadelf-add-additional-relocations.patch @@ -0,0 +1,39 @@ +From b64520ed1a3c65f3f4730ea1e1fd6763cbfa02c1 Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Wed, 25 Oct 2023 17:54:51 +0800 +Subject: [PATCH 42/51] cmd/link/internal/loadelf: add additional relocations + for loong64 + +The Linker Relaxation feature on Loong64 is already supported in binutils 2.41. +The intermediate code generated after enabling this feature introduces three +reloc types. + +elf.R_LARCH_B26 +elf.R_LARCH_ADD32 +elf.R_LARCH_SUB32 + +Fixes #63725 + +Signed-off-by: Guoqi Chen +Change-Id: I53a000d99049a14a7eb9497909c8d4d8b8913757 +--- + src/cmd/link/internal/loadelf/ldelf.go | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/cmd/link/internal/loadelf/ldelf.go b/src/cmd/link/internal/loadelf/ldelf.go +index 1dc6a3f1f3..dcb34b871b 100644 +--- a/src/cmd/link/internal/loadelf/ldelf.go ++++ b/src/cmd/link/internal/loadelf/ldelf.go +@@ -1009,6 +1009,9 @@ func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, uint8, error) { + + case LOONG64 | uint32(elf.R_LARCH_MARK_LA)<<16, + LOONG64 | uint32(elf.R_LARCH_MARK_PCREL)<<16, ++ LOONG64 | uint32(elf.R_LARCH_ADD32)<<16, ++ LOONG64 | uint32(elf.R_LARCH_SUB32)<<16, ++ LOONG64 | uint32(elf.R_LARCH_B26)<<16, + LOONG64 | uint32(elf.R_LARCH_32_PCREL)<<16: + return 4, 4, nil + +-- +2.20.1 + diff --git a/loongarch64/0043-cmd-link-add-new-relocations-numbered-101-to-109-for.patch b/loongarch64/0043-cmd-link-add-new-relocations-numbered-101-to-109-for.patch new file mode 100644 index 0000000000000000000000000000000000000000..81887a3b81cf230b375ea0a09d6c7e4fe39d6343 --- /dev/null +++ b/loongarch64/0043-cmd-link-add-new-relocations-numbered-101-to-109-for.patch @@ -0,0 +1,86 @@ +From 8e680810198c63c34f058c08bf09a37ba8125fbe Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Thu, 26 Oct 2023 15:12:29 +0800 +Subject: [PATCH 43/51] cmd/link: add new relocations numbered 101 to 109 for + loong64 + +Signed-off-by: Guoqi Chen +Change-Id: Ieb845ce03a039f7ee9a39f243145193b5f9ab1dc +--- + src/cmd/link/internal/loadelf/ldelf.go | 15 ++++++++++++++- + src/debug/elf/elf.go | 18 ++++++++++++++++++ + 2 files changed, 32 insertions(+), 1 deletion(-) + +diff --git a/src/cmd/link/internal/loadelf/ldelf.go b/src/cmd/link/internal/loadelf/ldelf.go +index dcb34b871b..2a013dde0d 100644 +--- a/src/cmd/link/internal/loadelf/ldelf.go ++++ b/src/cmd/link/internal/loadelf/ldelf.go +@@ -1007,15 +1007,28 @@ func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, uint8, error) { + MIPS64 | uint32(elf.R_MIPS_GOT_DISP)<<16: + return 4, 4, nil + ++ case LOONG64 | uint32(elf.R_LARCH_ADD8)<<16, ++ LOONG64 | uint32(elf.R_LARCH_SUB8)<<16: ++ return 1, 1, nil ++ ++ case LOONG64 | uint32(elf.R_LARCH_ADD16)<<16, ++ LOONG64 | uint32(elf.R_LARCH_SUB16)<<16: ++ return 2, 2, nil ++ + case LOONG64 | uint32(elf.R_LARCH_MARK_LA)<<16, + LOONG64 | uint32(elf.R_LARCH_MARK_PCREL)<<16, ++ LOONG64 | uint32(elf.R_LARCH_ADD24)<<16, + LOONG64 | uint32(elf.R_LARCH_ADD32)<<16, ++ LOONG64 | uint32(elf.R_LARCH_SUB24)<<16, + LOONG64 | uint32(elf.R_LARCH_SUB32)<<16, + LOONG64 | uint32(elf.R_LARCH_B26)<<16, + LOONG64 | uint32(elf.R_LARCH_32_PCREL)<<16: + return 4, 4, nil + +- case LOONG64 | uint32(elf.R_LARCH_64)<<16: ++ case LOONG64 | uint32(elf.R_LARCH_64)<<16, ++ LOONG64 | uint32(elf.R_LARCH_ADD64)<<16, ++ LOONG64 | uint32(elf.R_LARCH_SUB64)<<16, ++ LOONG64 | uint32(elf.R_LARCH_64_PCREL)<<16: + return 8, 8, nil + + case S390X | uint32(elf.R_390_8)<<16: +diff --git a/src/debug/elf/elf.go b/src/debug/elf/elf.go +index c982c684ba..63acddc166 100644 +--- a/src/debug/elf/elf.go ++++ b/src/debug/elf/elf.go +@@ -2365,6 +2365,15 @@ const ( + R_LARCH_TLS_GD_HI20 R_LARCH = 98 + R_LARCH_32_PCREL R_LARCH = 99 + R_LARCH_RELAX R_LARCH = 100 ++ R_LARCH_DELETE R_LARCH = 101 ++ R_LARCH_ALIGN R_LARCH = 102 ++ R_LARCH_PCREL20_S2 R_LARCH = 103 ++ R_LARCH_CFA R_LARCH = 104 ++ R_LARCH_ADD6 R_LARCH = 105 ++ R_LARCH_SUB6 R_LARCH = 106 ++ R_LARCH_ADD_ULEB128 R_LARCH = 107 ++ R_LARCH_SUB_ULEB128 R_LARCH = 108 ++ R_LARCH_64_PCREL R_LARCH = 109 + ) + + var rlarchStrings = []intName{ +@@ -2457,6 +2466,15 @@ var rlarchStrings = []intName{ + {98, "R_LARCH_TLS_GD_HI20"}, + {99, "R_LARCH_32_PCREL"}, + {100, "R_LARCH_RELAX"}, ++ {101, "R_LARCH_DELETE"}, ++ {102, "R_LARCH_ALIGN"}, ++ {103, "R_LARCH_PCREL20_S2"}, ++ {104, "R_LARCH_CFA"}, ++ {105, "R_LARCH_ADD6"}, ++ {106, "R_LARCH_SUB6"}, ++ {107, "R_LARCH_ADD_ULEB128"}, ++ {108, "R_LARCH_SUB_ULEB128"}, ++ {109, "R_LARCH_64_PCREL"}, + } + + func (i R_LARCH) String() string { return stringName(uint32(i), rlarchStrings, false) } +-- +2.20.1 + diff --git a/loongarch64/0044-api-add-new-relocations-numbered-101-to-109-for-loon.patch b/loongarch64/0044-api-add-new-relocations-numbered-101-to-109-for-loon.patch new file mode 100644 index 0000000000000000000000000000000000000000..3ae59b4abdf47ba3f70f4cbf30c3ba9dea5d3298 --- /dev/null +++ b/loongarch64/0044-api-add-new-relocations-numbered-101-to-109-for-loon.patch @@ -0,0 +1,44 @@ +From 7d1514713b3409ed3abb154f2889594888f0ed90 Mon Sep 17 00:00:00 2001 +From: chenguoqi +Date: Fri, 27 Oct 2023 16:10:20 +0800 +Subject: [PATCH 44/51] api: add new relocations numbered 101 to 109 for + loong64 + +Signed-off-by: chenguoqi +Change-Id: If078f7865e8d5c5ae963e79cf7157eca7e7a0817 +--- + api/go1.20.txt | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/api/go1.20.txt b/api/go1.20.txt +index 8deb435a68..6fe543d3e8 100644 +--- a/api/go1.20.txt ++++ b/api/go1.20.txt +@@ -118,6 +118,24 @@ pkg debug/elf, const R_LARCH_TLS_LE_HI20 = 83 #54222 + pkg debug/elf, const R_LARCH_TLS_LE_HI20 R_LARCH #54222 + pkg debug/elf, const R_LARCH_TLS_LE_LO12 = 84 #54222 + pkg debug/elf, const R_LARCH_TLS_LE_LO12 R_LARCH #54222 ++pkg debug/elf, const R_LARCH_DELETE = 101 #54222 ++pkg debug/elf, const R_LARCH_DELETE R_LARCH #54222 ++pkg debug/elf, const R_LARCH_ALIGN = 102 #54222 ++pkg debug/elf, const R_LARCH_ALIGN R_LARCH #54222 ++pkg debug/elf, const R_LARCH_PCREL20_S2 = 103 #54222 ++pkg debug/elf, const R_LARCH_PCREL20_S2 R_LARCH #54222 ++pkg debug/elf, const R_LARCH_CFA = 104 #54222 ++pkg debug/elf, const R_LARCH_CFA R_LARCH #54222 ++pkg debug/elf, const R_LARCH_ADD6 = 105 #54222 ++pkg debug/elf, const R_LARCH_ADD6 R_LARCH #54222 ++pkg debug/elf, const R_LARCH_SUB6 = 106 #54222 ++pkg debug/elf, const R_LARCH_SUB6 R_LARCH #54222 ++pkg debug/elf, const R_LARCH_ADD_ULEB128 = 107 #54222 ++pkg debug/elf, const R_LARCH_ADD_ULEB128 R_LARCH #54222 ++pkg debug/elf, const R_LARCH_SUB_ULEB128 = 108 #54222 ++pkg debug/elf, const R_LARCH_SUB_ULEB128 R_LARCH #54222 ++pkg debug/elf, const R_LARCH_64_PCREL = 109 #54222 ++pkg debug/elf, const R_LARCH_64_PCREL R_LARCH #54222 + pkg debug/elf, const R_PPC64_ADDR16_HIGHER34 = 136 #54345 + pkg debug/elf, const R_PPC64_ADDR16_HIGHER34 R_PPC64 #54345 + pkg debug/elf, const R_PPC64_ADDR16_HIGHERA34 = 137 #54345 +-- +2.20.1 + diff --git a/loongarch64/0045-cmd-internal-obj-loong64-remove-unused-register-alia.patch b/loongarch64/0045-cmd-internal-obj-loong64-remove-unused-register-alia.patch new file mode 100644 index 0000000000000000000000000000000000000000..66256b538103476b4ecbda4a7c4b2afb14852afe --- /dev/null +++ b/loongarch64/0045-cmd-internal-obj-loong64-remove-unused-register-alia.patch @@ -0,0 +1,26 @@ +From 3cb4673b4f2da0b48754622f68f89e55f6213a3d Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Thu, 16 Nov 2023 19:55:47 +0800 +Subject: [PATCH 45/51] cmd/internal/obj/loong64: remove unused register alias + +Change-Id: Id6447437ba5492f22417231badac4805fcac4474 +--- + src/cmd/internal/obj/loong64/a.out.go | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/src/cmd/internal/obj/loong64/a.out.go b/src/cmd/internal/obj/loong64/a.out.go +index 8df48a1e01..156dfda8b6 100644 +--- a/src/cmd/internal/obj/loong64/a.out.go ++++ b/src/cmd/internal/obj/loong64/a.out.go +@@ -157,8 +157,6 @@ const ( + REGZERO = REG_R0 // set to zero + REGLINK = REG_R1 + REGSP = REG_R3 +- REGRET = REG_R20 // not use +- REGARG = -1 // -1 disables passing the first argument in register + REGRT1 = REG_R20 // reserved for runtime, duffzero and duffcopy + REGRT2 = REG_R21 // reserved for runtime, duffcopy + REGCTXT = REG_R29 // context for closures +-- +2.20.1 + diff --git a/loongarch64/0046-cmd-internal-runtime-change-the-LR-parameter-registe.patch b/loongarch64/0046-cmd-internal-runtime-change-the-LR-parameter-registe.patch new file mode 100644 index 0000000000000000000000000000000000000000..397117bd9d379490a51999a713fbf51fa13ad840 --- /dev/null +++ b/loongarch64/0046-cmd-internal-runtime-change-the-LR-parameter-registe.patch @@ -0,0 +1,64 @@ +From 38b0c2fa58b7b0f5a9caa16ac863b06c57dec24f Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Fri, 17 Nov 2023 17:41:18 +0800 +Subject: [PATCH 46/51] cmd/internal,runtime: change the LR parameter register + convention when calling morestack to R31 + +Change-Id: I7e74ad8caf63f60a8caace3cb638bf88ea4630e9 +--- + src/cmd/internal/obj/loong64/obj.go | 4 ++-- + src/runtime/asm_loong64.s | 6 +++--- + 2 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/src/cmd/internal/obj/loong64/obj.go b/src/cmd/internal/obj/loong64/obj.go +index f1850f1caa..5033982cbc 100644 +--- a/src/cmd/internal/obj/loong64/obj.go ++++ b/src/cmd/internal/obj/loong64/obj.go +@@ -792,14 +792,14 @@ func (c *ctxt0) stacksplit(p *obj.Prog, framesize int32) *obj.Prog { + p.To.Type = obj.TYPE_BRANCH + p.Mark |= BRANCH + +- // MOV LINK, R30 ++ // MOV LINK, R31 + p = obj.Appendp(p, c.newprog) + + p.As = mov + p.From.Type = obj.TYPE_REG + p.From.Reg = REGLINK + p.To.Type = obj.TYPE_REG +- p.To.Reg = REG_R30 ++ p.To.Reg = REG_R31 + if q != nil { + q.To.SetTarget(p) + p.Mark |= LABEL +diff --git a/src/runtime/asm_loong64.s b/src/runtime/asm_loong64.s +index 3c24e33cb3..af41d57553 100644 +--- a/src/runtime/asm_loong64.s ++++ b/src/runtime/asm_loong64.s +@@ -214,7 +214,7 @@ noswitch: + + // Called during function prolog when more stack is needed. + // Caller has already loaded: +-// loong64: R30: LR ++// loong64: R31: LR + // + // The traceback routines see morestack on a g0 as being + // the top of a stack (for example, morestack calling newstack +@@ -238,12 +238,12 @@ TEXT runtime·morestack(SB),NOSPLIT|NOFRAME,$0-0 + // Set g->sched to context in f. + MOVV R3, (g_sched+gobuf_sp)(g) + MOVV R1, (g_sched+gobuf_pc)(g) +- MOVV R30, (g_sched+gobuf_lr)(g) ++ MOVV R31, (g_sched+gobuf_lr)(g) + MOVV REGCTXT, (g_sched+gobuf_ctxt)(g) + + // Called from f. + // Set m->morebuf to f's caller. +- MOVV R30, (m_morebuf+gobuf_pc)(R7) // f's caller's PC ++ MOVV R31, (m_morebuf+gobuf_pc)(R7) // f's caller's PC + MOVV R3, (m_morebuf+gobuf_sp)(R7) // f's caller's SP + MOVV g, (m_morebuf+gobuf_g)(R7) + +-- +2.20.1 + diff --git a/loongarch64/0047-cmd-runtime-enable-race-detector-on-loong64.patch b/loongarch64/0047-cmd-runtime-enable-race-detector-on-loong64.patch new file mode 100644 index 0000000000000000000000000000000000000000..8ef8cc6e55cad373323a01f38e9aef66a6039b45 --- /dev/null +++ b/loongarch64/0047-cmd-runtime-enable-race-detector-on-loong64.patch @@ -0,0 +1,4588 @@ +From 6d1b851be7d32908d1f862f5e561aa776b8cd0c6 Mon Sep 17 00:00:00 2001 +From: Xiaolin Zhao +Date: Sat, 19 Aug 2023 09:22:34 +0800 +Subject: [PATCH 47/51] cmd,runtime: enable race detector on loong64 + +Change-Id: If389318215476890295ed771297c6c088cfc84b3 +--- + src/cmd/dist/test.go | 2 +- + src/internal/platform/supported.go | 2 +- + src/race.bash | 3 +- + src/runtime/asm_loong64.s | 1 + + src/runtime/race/README | 1 + + src/runtime/race/race.go | 2 +- + src/runtime/race/race_linux_loong64.syso | Bin 0 -> 644528 bytes + src/runtime/race_loong64.s | 480 +++++++++++++++++++++++ + 8 files changed, 487 insertions(+), 4 deletions(-) + create mode 100644 src/runtime/race/race_linux_loong64.syso + create mode 100644 src/runtime/race_loong64.s + +diff --git a/src/cmd/dist/test.go b/src/cmd/dist/test.go +index 864060cbb2..8a1568c068 100644 +--- a/src/cmd/dist/test.go ++++ b/src/cmd/dist/test.go +@@ -1533,7 +1533,7 @@ func (t *tester) makeGOROOTUnwritable() (undo func()) { + func raceDetectorSupported(goos, goarch string) bool { + switch goos { + case "linux": +- return goarch == "amd64" || goarch == "ppc64le" || goarch == "arm64" || goarch == "s390x" ++ return goarch == "amd64" || goarch == "ppc64le" || goarch == "arm64" || goarch == "s390x" || goarch == "loong64" + case "darwin": + return goarch == "amd64" || goarch == "arm64" + case "freebsd", "netbsd", "openbsd", "windows": +diff --git a/src/internal/platform/supported.go b/src/internal/platform/supported.go +index 715bfb5e48..1589a1ebd5 100644 +--- a/src/internal/platform/supported.go ++++ b/src/internal/platform/supported.go +@@ -23,7 +23,7 @@ func (p OSArch) String() string { + func RaceDetectorSupported(goos, goarch string) bool { + switch goos { + case "linux": +- return goarch == "amd64" || goarch == "ppc64le" || goarch == "arm64" || goarch == "s390x" ++ return goarch == "amd64" || goarch == "ppc64le" || goarch == "arm64" || goarch == "s390x" || goarch == "loong64" + case "darwin": + return goarch == "amd64" || goarch == "arm64" + case "freebsd", "netbsd", "openbsd", "windows": +diff --git a/src/race.bash b/src/race.bash +index f1a168bfbb..ae9f57ffd7 100755 +--- a/src/race.bash ++++ b/src/race.bash +@@ -9,7 +9,7 @@ + set -e + + function usage { +- echo 'race detector is only supported on linux/amd64, linux/ppc64le, linux/arm64, linux/s390x, freebsd/amd64, netbsd/amd64, openbsd/amd64, darwin/amd64, and darwin/arm64' 1>&2 ++ echo 'race detector is only supported on linux/amd64, linux/ppc64le, linux/arm64, linux/loong64, linux/s390x, freebsd/amd64, netbsd/amd64, openbsd/amd64, darwin/amd64, and darwin/arm64' 1>&2 + exit 1 + } + +@@ -19,6 +19,7 @@ case $(uname -s -m) in + "Linux x86_64") ;; + "Linux ppc64le") ;; + "Linux aarch64") ;; ++ "Linux loongarch64") ;; + "Linux s390x") ;; + "FreeBSD amd64") ;; + "NetBSD amd64") ;; +diff --git a/src/runtime/asm_loong64.s b/src/runtime/asm_loong64.s +index af41d57553..e36bc10a2c 100644 +--- a/src/runtime/asm_loong64.s ++++ b/src/runtime/asm_loong64.s +@@ -37,6 +37,7 @@ TEXT runtime·rt0_go(SB),NOSPLIT|TOPFRAME,$0 + JAL (R25) + + nocgo: ++ //JAL runtime·save_g(SB) + // update stackguard after _cgo_init + MOVV (g_stack+stack_lo)(g), R19 + ADDV $const_stackGuard, R19 +diff --git a/src/runtime/race/README b/src/runtime/race/README +index acd8b84838..fc0b56ec69 100644 +--- a/src/runtime/race/README ++++ b/src/runtime/race/README +@@ -12,6 +12,7 @@ race_windows_amd64.syso built with LLVM b6374437af39af66896da74a1dc1b8a0ece26bee + race_linux_arm64.syso built with LLVM 41cb504b7c4b18ac15830107431a0c1eec73a6b2 and Go 851ecea4cc99ab276109493477b2c7e30c253ea8. + race_darwin_arm64.syso built with LLVM 41cb504b7c4b18ac15830107431a0c1eec73a6b2 and Go 851ecea4cc99ab276109493477b2c7e30c253ea8. + race_openbsd_amd64.syso built with LLVM fcf6ae2f070eba73074b6ec8d8281e54d29dbeeb and Go 8f2db14cd35bbd674cb2988a508306de6655e425. ++//TODO race_linux_loong64.syso built with ... + race_linux_s390x.syso built with LLVM 41cb504b7c4b18ac15830107431a0c1eec73a6b2 and Go 851ecea4cc99ab276109493477b2c7e30c253ea8. + internal/amd64v3/race_linux.syso built with LLVM 74c2d4f6024c8f160871a2baa928d0b42415f183 and Go c0f27eb3d580c8b9efd73802678eba4c6c9461be. + internal/amd64v1/race_linux.syso built with LLVM 74c2d4f6024c8f160871a2baa928d0b42415f183 and Go c0f27eb3d580c8b9efd73802678eba4c6c9461be. +diff --git a/src/runtime/race/race.go b/src/runtime/race/race.go +index 9c508ebc2b..9fd75424ca 100644 +--- a/src/runtime/race/race.go ++++ b/src/runtime/race/race.go +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build race && ((linux && (amd64 || arm64 || ppc64le || s390x)) || ((freebsd || netbsd || openbsd || windows) && amd64)) ++//go:build race && ((linux && (amd64 || arm64 || loong64 || ppc64le || s390x)) || ((freebsd || netbsd || openbsd || windows) && amd64)) + + package race + +diff --git a/src/runtime/race/race_linux_loong64.syso b/src/runtime/race/race_linux_loong64.syso +new file mode 100644 +index 0000000000000000000000000000000000000000..677bff08c831db424ef2ccf73b85ef8c7e6192c3 +GIT binary patch +literal 644528 +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 +z7qiQ0S~Ul-eP@K%Wn`fXTz +zze+d&lZ2%k7~H%O@O3R8f1He>c94cV#sKYw4nS4Y1B#xEL7WmYlb<)%74Xe#8#WyN{R1l! +z_lrnnzR-W-(NltkQmvcn<851&4<~xc>OS47q%>_+)?==^4DrAZQbo&<2IXGB@{wo1 +zctXh*hbH=R*Bxk6_n}P9fi^9QF(yaZFLID}aN?lcL*tO{X;(iwiF8l9c5vLF+$WG8 +zD?6lJ-S-XBh9C|3-LkS=9?BgHu^X(ip1D@VDnkXGJJxwR;F2x)6OmpceJ +zH`TYRJIZyjuD)GsJg`;y2Vkwk*ta*`ni3uinM+R<>w$NpCtDoZ3?IrBsTdpgF<%oMkrf~!K +za^BxW^ahciqKmYuw=jMemn*%6ktUKwLG*HwA8ES@^O?aStbHoNqq9YLEye@zbvRpO +zMmRSG>}x);#=AN*lJlvk^XG}kWxm{S+r!?_>)Dd8eW*XY0d@goFI)n--xPo^v0e@3 +z<%wO;r8OG{%X~>?xluHsI-fo+#T5xrvNQ +z%MJH5mE{MlDM9kPX(_A+KF<*);AzS0>v~Q?TqRHA`|zpIC(P^Wc69hHm@?y +z@hY@dWQB|wv2on}E_LEsVUNRZ-umwIhU&ZIJ8+hK2kd;|;(FB>jQ+tGS?81Elv}FgWQm;h(x|e;|`zU1a +z^kSv)^8O->KJJY+0=e*W;T_|9aJiWV+df?^_lP0ad~J;ly#+gG6VgDVP=YSuiJ;G5 +z`smTC*nc)1tMckq6FgT{j&LHvdW5$i^fajEZ3qE7`N&Kay4^R9P7D}I0`%mrjoBiS +zSFcr;)JvLER}z2gKdr(PgbA<@to?{1OzrgHPxno}PIQ78nL;-7l8Kh1W)FzA4^_ilSIs`*;Q5f}yf~Hcn +zB_P%u0-wPSW!Zc4rld9c-}ctRPD)vn*S~Q~&>QY~od|Cp4F4hYSB~Arix{_i+$W}m +zgCfg#K;)-Hm9)m3$Gq#ITQJ@$M^RsIz>rp8D1DLU|8TJQaEOt$&tqg^%vDyDTUz5p +z{TtI$0a4I=7vwn6R1j({V{DyOlOuA45R=v%w8m49#p|%%=t=6Li-qVH5kjjr +zU|$w^w8(oNjkNY7Jp#M$V%VsD@O>-n)H>+3>Oj2~5e>)_!pJGosz>E%bwjGWly_Oz +z-U^NU#k#2ntBaApX^dSbzNaLF6u=G}cAFN~w`nZHdVRvSiESHIIJPOmCQ~zn2X<$< +zv`MR@^;(sgry0R9nxQKA-q6V&HB1HYq3+_v5)Q%;j&4IdU5pgAy&X33P8&S2!v+sG +zb$knpkVgLS1x3GbaC=8RI^!Xw>b|j>G1m)t7HdWz0d0k(ZZU&GU$QD7gijQN5=>=# +zK+1+%`HelsxP8cZk2%uL%Wn~nQ0sn`E~;MdD?*oH?uC8~<)({WUv@5M=Gx;L$Jt%5 +z10$nE?s`1Tzy6qYN8RW?g7dz0iMkTGoORi{&~4Y8?9q3fwiN#$@cz}FvTz#4^ufB< +z$noUY0^Ts>6z>Y^^M=bY?;haM_rVVE!QNUv%v0urjg|d3OR3ukA3xw;kB4;q5aWxv +zc3V~}#*42#mi8gWpGL%&K_0#yg7-X24G%Guuk#QuvDB|i5SAk>N4OT@T7>lo>k%G6 +zc)-&9>#ZquD8u^q!e*%hjEoRAbSM3CQMMlC!vjzs$}brv%Ia7@>ZU9b +zCik7R-}Mi>pIn+q8|r^qh0u$cQw8MJG_~EM;NL7?DCR~nZh-$wz}NE(Q(K^$+QOiz +zRY3>VdHyP@5=18FBAk=Fji-^acC-Vh-4*dk0NLe<6%sC-f&_+nq1U +zl}vnFa5z;YU=i)qW1@5%#)Z4_PzNyoafLQcxl)O533zUA4TvlE2ZXiw;H|#XhO+W< +zQThdJ9hM8>0gNhOR{^sMSXIES0$vsHs#CGnhI$K<#8%~tr_y8@)@faN@K%n8$J=$U +z^`=$m*2nm+kgoU*L*e{==cvA-c4J?GF-rS*RJxc88Za+$4@EIQE4Jqq9LM@EHZ^xF +zbH}kHBP83eoZu--n&6ohcuvckA*@<%MtTc?;o|Hhi%m=K>rfW8)+EpW|OwJKmk+zKJ@q +z=AStiJO_JBt2wQETmB8U2XrFsJJ@Ghig-uLPR%sv+7hAdgs!9>CBL3T-WS?LSyGds +z@cXxSnGy!tW%!!}TQIXFNn}#4!Vz8IeOU9Da;@d&a*gsxxGbyb*5>m>CgVxP6^hR* +zG`@3Q6JDDyd_C}3j7KPql@cF;7*)| +z0auCFh^AYAfH-MmwYC>dHBZBS*{01Y#{9pjK_mT`uOzrln`bs?w4+J0;V6^n)WP>d +z$TKZyO8XjlrLS)~;6PpQu{5YC3;)VCX?MCd68qoJIV9{sH@((9an6 +zTQKgUj&qIs7>88KUS+D79E6VQ_y7en-JYkdYIrgtB+weN*iN7->Ul_?kUrCuoyRyx=IlIIG +zZICyJH_Ho0FYujx#`;}bDV~R1zF=FdJKm0FJ8nHLKe%;~mhp51P2~LTE#Uhx9+tZZ +zV>R_@Q$LX}28n{*IRRoIG*oQw4h6j-sA0-!f~DYARiBL)~5iMsI5=VR&ELUB)-gd#eU3{3B%6hymP|QioPNY2j2nA-;tMXN8yJR8KQvg)?yAqowF5kP8nt2 +z2G7yo*xNVa&&b0*XW#!8apF!Hpgwl{Fky-)O2UMg{)l|=@E2EzvM-f8BmY{li_}piRO2w||Z~6ZyirMzelz70R-oox3dUYS^SP`i&g0AuIOG5^jy0#AGC;H=a>ijEHE(N06dFy?3)Y1jzU|U +zXBgQYo$wj&VT}#n{Bz5d^YI?Rm=Q)>=VJ_`Ze<&TUNV%y%M8VMM(C^CM9~dip*}O+ +zQxyFQx)^D$PNbelL_YVO_+nG0ZX|g0a8nsUbozC +z&?NU=QPdx4KGYBUNi!c7dT}qI|N9&SSLvr3n4uSFEwO{>Hk4?O88ch2)PL +z02AA?7Ng(cM~SbaD-Kr@e$c}jYZZPMzAmm-|Bim$nvIed+w)558Ny)<5IV=NF!Vxg +zPI4~C^B{PUPfQnJT#>pU4Y~mOCvuss_v7_}4|b93!)DnK=){m~FTQ1BT0B3Km&w!Y +z-_3ZW9KkQ>?Z`JTAC_5O>>xoN6CclM@jy(i-=GtRuP-rGf3l%ef<_UfFKH^*4goF`Wyq&~)Kv-E$u!;69s&J^ +zL4L8ep)Wn^)K_k|5l=tTI^O;#yiFHYXrLR`aBW+XYgjIgB#dZx7j}|28(Rg}(hXPuer&=c>e0V=itz*)cYT%>=x4k~@fb|QcY&v=UiuT0(MAu<4U+Jne+xo@ +z#RtD^IM499{`o4{ts~)w?H!;E{IlHm?%$SW=GeTl8-0&CgXEjt<#F+PJ5C>6_!#E( +zpi%V>YYNLVf4B`kK9pSpJBfW70__<_g0Lsj@5v3p-xPWRc59QBPB=md_WDf%_?mPL +zi4Hztoj#l26=R2 +z$gP6^s}bqPMknXeFUjT4re)(Cxk3P%ytGoXW-cq=hyzKt=Db47kaQ#+qAc%Ed(7y%rC$4qq +zn-3LzHFWl$6P~1K`C0u#oI^K{;a&~csE{k-U_h=RcT)bS2c7vs0ml`IV;4J*dcd{w +zfafIWtxVt42DRlv=mm_`@#7lDGwPDA-&ikopR1$7?Ikut<90MC60pF{WygbjAvwGY4^cJOs^O+=g2BS~oU;FxXjD}z6{(2!L70Ve{NkeFVdOUl_%6QDTMX* +z2*y+&e2@|N?FkRpx84u%IxO|52XTom5x=?uGJN7&Hq!wGqLZ{!c%VgMP +zT-j*0Fjo3SsS9TmJdqGc<(ac#Zk}Fq7emi{U(&-}H==DzeL~wc0W`RK6ll|A&vWM) +z_P(qE_&x*s-2nfj88}0=6nPV2pK|`x6LHRKnHF#37@5#TO`X?vn4j}puI&UtTfVz~ +zSeE~;{Exs6c@OO!e$VhaK9d4|tHd|LkqrHMc&VL6I^eIMyLpAHKR-d9ChX-oXy=_o +zJ$d3nQ#(1v)DFU?rGJrghxmEJIwvpnO|Quv^z2m}7hh_}X_FF9$#*Ch&vRXQCJB1t +zoaxXPXG`z3u5)`a8QABQdxMj%qV0yYv|Kxs@aX5L?;!Kpe8O_nn=jz$1s{9DeeWoo +z*SYC(y##6R#--OFeF>h!&=qbz`U~cQujZNXpF}(S1g`&pJ`>LM{)}e_7ZXGDgBbh&edwRZ*{sdesGnJ^z-xhPk;r|1JaHuKuGng*rE$ +zC(!3w24Fqz)JeYPyi?YnDe{}n6Z#48Li`v?d2;89oxY=-`~AO#FUJ4>zv4^&;CzCz +z*aHvuJ%NS=)H8F@-_#}UJevB2zBJC6-@-E={e3?B8$PK_(4T!kz8Qxw*4HZf8vTsA +zI;|CV)hX=fr$0eIzsY_+rOd&eijv~(+T7rF?M<}RD;!b?W0Ht^$;&-XuTe_z&i0Z- +zg0IEk#(=A$SMno%)i54?Sr(RE5Gyh5$*kt4#^Yy@HCd^i9jRvpW$hI +zKTY(-yyfqfr(feZ>_>wx59h$n`~lV)cBf&#B78{|rd9?#W`#v&E6O%E;2rDotti`? +zhxE@3t;{slS5dYOWx2n%47_|3_P5ocj=HO{cOE?1d||yd%P`e4vtFHcpPuy#oFAAG +zEYG^TsXS|Xv^)!V!!9(n=DU!u0Qro1RqiXoymA@#6eTRy#ZlbJjOAV +zd5!x-K5-j}_m$U)GV0ePbBWZsOec)gy{_)VYkoXDsIwCdP^N&k#&PUpKVC5s`+0%) +zrvdTQ5Rpm$HOqEgpOO9G(63jqq1bkuZEJM0C34H9t>M}dt{p+$-79R{A@OBtqrAwp +zf>6vxNrHaonBPj +zeqWAP{qa2AoF)d9rU_pde#@VVVjub?Qqo_H^a|`3ogrW;=a+d!u<97b1MDlg*DHqX +zKW2>$e+B)20Q;Aj$B#X`NtpL-1)Z8eC-cm)4eiEkW%iHtH0Fr#&#}M5_Z!~$HB|OD +z*VfqgEAKOvRq&e;2jWD&6jP~y4+KJzZ_ill@0iN@CjGt%tUI>O?%Io)j=f=RBdl%8gYeE%dYi*)EG|HVkZ7U>@%{cEJB{!**nhxB7e +zhtBo)M*8hYzp!3CGNxXQlpuY`@3pGD-)nx@k^WZj_`OK~8PZoEeIwHENBVN4V;=3_ +zgY*idHz55pqCGzP>)>FphhMlJ$08>m9tCp!yn?WM*6Rj +zeiza!kiHh_B}gwvdJyTeMN#XkNc#|expzcn^+u%a+l9U1Va=CmD88FS5oyCc;hg7# +zUP_+=oFxFQ*1wOv>+mtYR<4VGjP~Uo!}*$Jc%B$NDEA_)3#GuGy9j%(QpOnC+&@`U +zB~M|!@_Q&>Y?#^w)>dUO>K=4rt8x-H$;eZK1?#PS4SG4EWIn!J$z1Y`lKE)P2kO#^ +zAE=YJiK08a`^By!*f%%qysV!Vn_8)EYCjK}+TD;_W4Xwm7By9l733e6XME5r%W(F> +z2l;&hdt|8t$v265ns|g~G!zm1<*(Aj%)z+RLxHSN|3SC7x&(C(M;j{IQqiVrv?%$_ +z*u(ZX_A$}#*a&#YE4zoCry0{lzKdrr;K&GyX~feSY893lrpj+&oV!9?%lOio3fWL0 +zKPu!yg-ocB2^BJ-LMBwmk_x#{Ar~s-0`{$KBixI6MuS#=fzNsO$-#nW1U|w3g3-qV +zVmJ2s*P#zy1`odk9)1D*><4}Q*jt``=?B^@(^P|nA7IZH{AfRaOnZB@QskSYO!K3@ +zqmTvqoKt$BUe@y_?&d%}M?LncyscgYXAk@+DWT-b}CZ&Iu{E#b| +zA95!14{-8Brg}q$QqJ#^A95!1L+)h$uS8J*JiEJou=oe$tS@-BH)Jd20=pc~S8M{E +z{sH;h1Umf#^0kMz>4hcLTF+b$-Bj$&EeuVsya>yd{Lmnw> +zd$7mlUOdd(3i;fFysePYJ)=w@}vKh1i)E`vnTAoJougkaP^?vYRKno$Y(X=bM_cRtNqBDnsF)Db)okmqwq~=*7&wU$`N^< +zyiXaRELc6-3h!>h8RMv_&Hz8}aK;0-taUNV#nm(7w5-Sa<+p{i%3evYoAtQ&hP?~= +z*X;;+Bb&Y_s=g=E8a6WE)LuB)54 +zaK~}@@Z?!1e)oAz_{o2k8}Wz>qv>LD3ifhWdBo6^qt+d4OZ31RWx2>tK;6{>>)g)y +zGuK9-zN5X;iZcrTw5>7#c69NXV}AU%5Za<^w4;Pze<#)&(uQ-(#OQ|k)Ew9moKF!B!eHPmF6U7AuF|jS&ZDNs +z)xD<48b1yG2iTBl%USO)?Pk49x@!?t6}evoP+#Hx;VF6?c8S*LIt)*|zkNF6A0tg|ZWJLO&SiAM{PT^A6yXN&aX1Tx*VC+%m8p +zMxMkOjo>cuWN+-ztrlWP?>L^^m6M7+R5l;EHX~ui+*9I#P-We$lRnN}3^50b!IW@z +zn0kHGfkUrANFm%VyuEOC&yBmbJZ)&obhCnUd_xS`KHgQVxv2;H1V_N$kF9U^+SF0L +z*FUg-JjZhwo{#lf9hWZ<7r$?@l8|rr8}r8c75BH{P7Ta?xRPOzyoO +zkucOm9x;i2K;O^`>F@K6h1^Bq&xU<65BAA?*eAeIJy@X=NBAA=b(3C$DipVkAoz}c +z%S6~?s1N655J$U=C(I=r&}n#Fo$KnvdB6+&q7p{>VBw3vzC3$>H1~3CJ!y?^{tDYSd*04b-$7=L6Q$eDknpseS=zMU>{QyI;hx``wW=JeT;+HnAMxyav{V0wEMg}{GUv%$Qd>pR8H8ln*p +z`YibAeXFph3H$8ZdwB`Y198j{R>TS>`n134$ +z+T3F7r`k>U#6bF^;&I@94@r|+Q8Wi>Nv91(?#l#Dlr{4FD)27;CS`0A(;)xKD) +zwyWXq7b@*f=8xoURqEg~+C4y&)+XSr1@>dcz8$k>GoRqOX_Se5UoOg+kLU9Hqpb|U +zN81Ny<%b)^So2&lSO5q3=P*Yq#@QCr9+#&RE=sC7SzZGHVt-`(stjFKMS#ZF1obyt^e0&V_i;LqSYqoW(eJ-B9aq5;D@I(UU +z6sTAB4|SP@6Me^Vlo9I}eCBwFG-*?XmgDS#!{3pEN>=q%30YP7;6K#Q +zwG@2Q*td|QVQixc<+xX+8g=+c3)qEK*ee}@->T(u?0bOzt2t&(Auq9BmzQdhzdJok +zSs@>APvYjFeeS^3cg>hHa35UrnD7kQYMc*W~N +zSC_{7fmgCk9r_I6Jl*yOyZ*t=_=dkp@KdYjTb8n_3BCd5A0o{l?O2nCcS2# +zU!bkS{QP!e40J*i?HjgV{MsHiKJ*Qv9W~S(;QhVWTO{SUAbwn6d)9C0uWrX32lid7 +z7~iyoP4+#j9HZwJ+vD^@&^ZqqrdABti;M9Du`Ul7Nz1?BX~Q!JkKyy=57d_^BS5FS +z@r=Xc+PhET%)cA&8nW-%=k&uetsHxv+&q$ZqV}C$fCqSWjKz!0j{CbR(H3Br<1*+| +zP*!ZJtH2YR@qHDhQ>$irN?BJ|I?e??Pc7EPz!9SCsVSb)ImmPE=QgbmerD5pKJsuc +zHbbUQ8ETDB0?gDiv?*z$?Sxz;s!K7RNm@_(9_TO->FldDNM|?!au~+_AI9ZEhb^MB +zjz^rbJK|_X{(N>4=(Qpsc1%r``<31F45YE#VZh8bS?>jX1L6eUzc&2i0$Wa*9);h`qF>|XovjH1FcXmc-Xebx=SO^k;j+^^a9@8R1V;6}Z( +z9dMNZzXyTmTmd<6g8nhFJ`u%QiUCDf1z`sZ +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 +zm$6Q@;mosruFhTGn`dI*KV*oq#@`{syw7Gn +z_>JfA78cug_HZr8<-0B5H{Rj7fP9DF9E)BJzMIv-cjp`%KJiS(eby>%E$WwxpkL%Y +z?N}do`EUa4%3Xlzzr~N`=itY?ZGLp&BR_r(eSTJc`~mp!KJX)S`9FK7&pG)r)P*nS +zIDC13XTBT+x?J`54*smVqk}(}-*F~?K1=@O{xp;e8RcHy=Y+pW;i=en2|nFRK1DxC +zKE2J=^~oK&{ux`>XUFUM+eC-1zpXQkMn2@|di0UxSNKC?y8iFBt|!kDmU!BMr($O@ +z7eSUEf@~Akc_!o7%wjol%UnF&*|w(6&`v-HLaW +zx)o{a4D>N|t>oWZy3wo|P+j-HL@S@P!msLi)7kGlGo_n%4K +z`&*m;t=HP*ejd(sIX5Toa_v7nq{0i^3;w=Cn+takjzouC~E9p2-(McW@5Py$-yaBYSAQ$~6S8pK=XL`VVl2T!|O=m0-P{`CF3U +z`^CK~Z(=T3wa=Q_AG&Ac)c>J<@lWV;7Z>XD73Z=qvLFkWK^B_2pMQgva*u4h@8g_u +z(TzUukNe21-siSAE;_$MpXZ!^raphhu{Sao+haUwNIkxRdK`Tz<>2yefEQv|9PIYx!}<< +z=+9k9%=0|ONgLW=$IobrYH|FBL#?=U$F^(B| +z-u&kKvAzX+l(v;0y!;B+Gq9EiTeH)??N=fRlTV|~=7t7!HSC+garJ)N(13N&1TX84 +z9D|H(^yWt%fQ&fx-ss2(_uk%wdOPjC%}bcveAhO)Hgp+m8KXq#y@6jf_WpmZY*YFM +z4TbaET?Z`uKEgKb5AZ2QFt?5F^XNxB@2V|B-c^^CnEXAQ;Z^0P#`8VPOH6GP*1`6| +zw^@a}$iqA8r!=8FY54^9M)Cfd@Llg>&uO_*i~Hda*LFSQDNWJgufblO6!abTgq4LW +z-c`9rQ`%M)?`lVI-x~L-x;9oV=FzTw)m*Vni^5k#8b#~h$6aj=8ts1C`_U&n`O?n~ +zd!O@X+SulD{2mhMNZXsfCUUxzPT_5=O% +z=mXw)XFc3rScSPNd7I)C@iv2>Q?ePr&K${tb&gF`2q?v8S_4ZAlgF +z&{0kJ4Tl7j3k8>Wr@@Zncy^Q5?!SG|Rg~30`<31`x15g6jhcZ=4#r!6 +zD)(Ht2XZX+czI|4!k!Y(Wby@d2kW#>osu@l#;$WZ2mT|k+I>#hZGE+i>|#zQZD!aF +z2S00|-8qT8&-w{BbphMh`pu~r+?>-9ZWHIuVspB4wXs=9cxAnW_xV$WufWg1I;?9> +zNqbqwe|f6V<$dC24Lw!JGS<&e+4hJ7pY{3aLeg5=)u4BGHVSmA3Oy_BYWBwhqrvuR8o5+U~)kls@eg_@S%J +za&0~Iq=B))gsu +z)-LmGcfN8?TgmnRV17-Ti1U;g;ANL~w9D{5oOT)KEU|gY#BS`feI2^v+-=(Pl$d?i +zWq$4Qp5)26y`Jv(PV!}RtgX7~J<$KMY^Wp6wfVr4-QGLEz5>qDZ#*ON<+(1wwTETJxK|5f9oHW+V3*M!&b5m9kO{6u +zaBbpu__n|_HOdCZ?IKQC})c+Z5m0LXd{<}NoIONm4&Un(*2HAVe +zGnsqXzQkNUjI++PzwoXtJ>L +zWac1brnqArf$IjKOKdH{-52W0NX!=cF1djZIwm(||AgG&_k=jl-xxQ~_w&3mY(v+l +z>C*RW_)X*eXnX5Z#ra9PA|C60o`2Nwp;BhpcX#XdJpX=-zjA&vx>#@I{#U>kCNbGWT=uRHesr7gBz9a{taE*Wa>u;*ej1b&b*bhINa=0Et3zM~w( +zdXP`J=sb==A9Px8 +zpI>Z`SqlLReGelE2WWwPwPoC68uoVVO}H8~r(fa|Jjd}2#Jlm5(0!Dpp@w!oV8i;Y +zcjYWmcI!4#cH0b5cD%t-uAG8>q!;L3;}(%W68ymWtMD6L+sBF0dxwgmSFp}qhj!~c +z*@AZl_eNbQR}RW;f!`sF-}D-Jfhb#vIZzdTXUxPNvMqj5_9WW=u6tED|98hE(hz%O +zu@4q|917$1I6!yC_-2{CSBQCCI{p~&9(MPH;J%s=>;|S+!N>C+V15bvf*RAYW=J0i +z`mqt;uzsieF<;zw$Wm%w$9~CWu$QpEry709^@r{QrBBEH-KMi(N16t +zeuFH}{=Ks>>Zu-LYWQupnZdK!d&QmYJ;KPl)xtP4g!8DnON%q?v(=sVR)w)|ZOtDs +z|G{~wB{(<5_Gp*!95Bxs^UU$wCah7L_1cT^dq+lMUjpdKF@gK?n!glfq_NMjJGnnY +z?vKG9g@d>^f_ntQ_)UuDKEdIuw%B`tncwwS#Gi#&iaIlKzL+?KMj76o?9WR~DI3G^ +zoo69fR;Z#NK40=#@^SCzu+K5?$9ZYyXPv|2>KTpr=t~XnN!%-OcK|jfc%5rqY~$dC +z2IWHu7m1=1I7926w+2mA&;&kn`+OGhCZ4ppxwl=GNyB>j1#x_fdZm1C=#cOJET`D~ +zxdeD0Lfo|-+`XPIEd0(qw1tNOJ~w>^_DAB}g+hAC`XLkUnHe`^Ik#S(U31G4N9sE2 +zwN>bMo~P&CKmOjjybp-K>ly&u)P2xl@*F|$t^dLqd+eKYVc?h{@LLbmg>FAkAIjg) +z(J@ysZ2znDYXUC*CP)H#K*)XJ@~rItV{l?_;=;*(l>8M3ue)FD3>f#==S3-J?0f8= +z9(in`ht-%BJlYTeoZTi??GQh~N2C?ca7Iotl>_lg&+v +z?!&&XrOzm({qaqQA71!{o(!FrjI*Eo7KF_Q|L5?{81H=8kA=Mw8sBNpA{@~l{XQSO +zEq^lv`TJnLy?6Cc{N^L>J;D3VK|{rIgd9J%V@%qBvEeYzl&<(|=W{27|9qq`P4*NA +zuY(Gq0Vfa0Hml^iqDEq&%#_H4YTU!`|H)~2+ +zE9foedJ0;R?$+~lg)T0|(>f0OO-%zQfJDJ&+-;%v+P=Xkz?*1WuLkZ(2eR!eLY%#Og +z#2GFVXSr}wxu^~GIZ=+z3GI>B}i?gh+&KMt^2 +zGc5Ry?0$7=>h>>bVJ&Vi+y@QZ~tVGDC2$_^2jcyE{+q& +zX-hf0GP0q4iq*p^)F+C3wqu=YFKjV%;nPuXiI}Y8_tzyq`i102>o-{I1)r10$sc^C +z9I(cA{dW93)b&bx;gpx##~-I1_I&4aGAwsS8Mc2Ze!EYcR!Z?_`;&DXbS3xeCUg<_kwsHs7F$ZXIajy7o1&=2OOMEx!FOXBYmr|rW2#Tx9Vorb>o +z8@@dWKbEmMNgoWjKgK)vIt+TkP%Z#n27*WWVK1FLOEgau%|id-8l1BApbzPKFX~>< +z19v$l;e2uu&QX7Ajpy0Ik#mwtXQ7`r<2=oi_?-ak2Zd~JQvtIIm{q{60%jF3tAJMp +zyei;T0k1j@x(s-Luk1TjkD%`TeoxW+pwq?JSJ?_aWn0;J=NNiZZ%-NhlyBsCifRX7 +zk6)rL&rD+vp6c6BuJrk`T)7myI&zFCdUdd8azX<3WTIRe9vmVn_U$THM!u0yCue;D8%KlRdQ6DR*2-+z8{yYllSU77Qfk@7p+WIL~} +zweIi(2JWRy!+T`8HDwlHxoM3k#bwQQ+mBgOqL(M+OFm5Wb`M8phhO5W^MpzmkDq5M +zESk0qD!*yg`ya$(Lho1TZFpX0>=I-xCg7vn8!QX`j*pxP32ykFWL?5f|F5 +zH_f(Yiz>y2>+AL@(Pyv@LHU@a6t!SHI2^=2xZAusWKV6Hm!PBnRr(*K-#kkceX?08 +z+k?J-B~hr9HOf&K^3;?n^i<&Q`wYJYah_l~&5tu5+>h@cEvB&^x!=lw?m>R0eG*a1 +zub*T6(n?hu_4$`ENz(6QDuW=v46s +z;B$Wk?yvz4#&Dt6B2N|4mLudI&i(kUsIn_?CKCCUL)Yt|59-tiPcO8~wtE7{n`Liti4JZ +ztT;U-n(fI?4yFP&+{=SKkFTL#DLa7Kx}d!mT>xWUvpR6 +zcnf|!mlw%{@(kZGoB(;WZ7liETHIE66!o=09w`@;M{6xf_7LW7 +zb8t7!++YLjN->=0>8MxwALnoWh)I5w>kXfI9m-n2!FmMV9~{A +zXiy$122DVZGVo=5S-cNliM`FF%hmzbcwZ*=s?R$$)7t-SA@vmXjrIFeg<*soudK&U +zo7R-hgL~xt3UUm=y0okpGAeB*;5Jpa +z=T_JEG`zfLg=N1hFZ-YCDC7yO9cXi-9rw*F(CsrHi$KQ`;KX@6+idG0(m3xYjc6NV +z?k&%9b6?{?+&RWMd+dA>Y@F~va1Le}bP>)QEr6cnIQ#AO@DtpfE#L>idElSr;;xjj +z^l5QF5ATd&JI?zEx2`pt&$M{}mzscm+}*8vz;~ts_L#4U{6$>-2KHh?9*FCz%ae2G +z8Mcp&_;KF^=`g>z!~aIyiEGAU+#~%z#W(MNhOg{%;9QBjK8Q15hwTiXwQiqnA-)Ol +zvjex-xgvM&@9t9#gT|ce&tty=&y~Q5b0Onup>q%a`ifIR*}tWmKI>8k&%o7yKc*T|cNOq=!Yg4v%JE+) +z{c7-A;UPRV*w@9qT{Q{tzv96k&PLm7>y;-(X)4MsL%Hff7&mvof3Y)79D!V3f^nfb +z!Be(Oc*-Koj|WCxfxjR1x=^J(aRYv@47%aia@@lLeVzSAA93ktI_xjgi*&EN`ycwc +zb%?24dZ7h-Md*LO1;2|5TJFZP1O56@iK)I@jydcA%=6MQ=UZ#4JL>U15%0K*^`iqF +zY5Yb%qv_d^#os^Y9QW_9TQgZ#Bii7%efa(J%z>hGR6kL618k|AAvgS9@L$$U-nksa +z{D?Liob`^{}J_oJ(-( +zW4o-Ab(er&;pEP!e{Y8Co?;6*(ZJowEJQEj2et915@i?CwzR_PMan9|qXC*jn`!e; +zpEN_kr49uJ*NU>Gcca58Yw_VxzC{6 +zHQj}%$6fEByz#e{6VacDM*)FM5xE{k?J +zhw!7^ZjVxw{k*B-(W-h1wKwwbL7lz-TCVIlTb*V{omGAt?rM}xL75|dF}V(QiLB2b +zS6|aP>U%G)KKxEL=}?WbDJXL!4}Pgs)Ps4pgv&ffJ$vKoNq6c&*%XvLlISUl46t#3 +z8do~_K+m!nn9oCI*gulaSU-!PA4ng}4b-Q*r2D_@(g(Y6Zqg}_GHNZ#q8_fTsHgEe +zy&~UJzn0J>YjnJqggi7WNR-rP_UA +zZEY{CgPqBKp&x1>;I`)2^Iy(kV!Q(!rA#7p`6iYI-r&8-GX14)(t(dm+t7Vltn8n= +zPk+R%yQ%whSvTf5E?i-0m)LjDMuy-F4EUe=nl>NDo7y4x-D}9Rp+R>RJNB~<8HN6~ +zyr&DN2Tg4)=JE(t+^sv7d1&)c#+fHbJ%O?I1-w_{;W|qR%CHX&{60J4u=VYH-Hri9 +zhyRCTApQzmTC(0wa#|Lac)9i0U>tkVfUod$werX?QF=IIoZ!Br$RMBn+q}QZ5Vafo +ziSVF7xrDQGz02%=_;XdKI{BLib1-+B16VMR#Cn5$j~jpIfH-k}kr=Y|m5k$F41P~U +zzwn)L-usR^RFnrD?e#K_m$WlEhRp?i*axmH(FC6b>FU;jbV+00q3YU!F5Q{t(!CS@ +z*t_Q99|HcNv;q9RT5s@dcnjQ}Ejrc-xJQQjUwBs*@6S5heOb8cO5T}e=pOwk@YZjE +z&j9qp4S&(I?)+TOx)pLrAJUd92Z>v8UaJ{2Y5T8$XnR)Bcb>Ti_v$apgIs^nM~wb$ +zUy<^IzGCzbd2bNzVEo*ga@*ll(GTUht`Fn1fcDdyQ{}w~ng516UpWtIA7jsrPCRF- +zKRN|p6UOcfU^82%aIZi7t`W?wqRT~oBGPClbG}ux3^wy=*zo8lo*y8*vhLsDjtT6Y +z;C)}`y6cN~eDS_7cOMM|+1dM1B;lxY|DMB(KImC93oq)$`0m0CC$xSXAU$haNbfYFFNW`Ix5>2K-P2!*# +z8LFFGOaPNOXEa~pSPBH4G+vTS0EK?P-+#ZgtE!vo2Kvi$zJ8wfsjhnWW$m@sUVH6z +z+v$%*l4BT?_^#t!vd>5kYx-2API&qTcxswTjM?|_5&5H8umU@eay{+hx#K0)6|wp$ +z{@3{YnUQ1z^P_yKKDm#MBUie2YGcg^)6hIB8{a%7vY?T6{_x|@c|F%4TWC-2$q$V& +z#TiRs9Ukd3#q@uZ{eJUcv*=>>`-?eW?hC(f%zwWx-|tfo7~5~xJec>?*~WS;xOAm9zA3T{O4Vp)@Oq?V%ywbY*W0yF^@;# +zDwq}2I^5Yd$S*0}#Ng+m#ZF~6choi|!HMbcmOuwN#5v}KdD3q~!P#`+y@uz& +zm*Ii?tL?d2xTymE<^zLFa}72-=KBD1bl_it>nrl((|i4{yN1_L?1uOSGnj5a{&$tXW?%A@$5YP +zbVY#=wQy$hcZ7L;ntl08hI={dG?9S^YHejWqpr>puZc{%BSKsYczxqSe;hgT61(S_ +zh9lo^B^J4j+;FW4e*-ymwk;p0yO$5~zI|O$UamSD{~C1WRdf8rA@1^!ejI;*WHY#G +zf3-DkqHPKERH-WH;>gIh#1XG8!S9kSPT(toVMPXgG-U%~fJH}#MsnXaWhHw*1)OR_ +z^%;w;?|4qGtu=vXPZ4jxYVi^);zjK?aaZ^X^k{d){Dcp!`92T$sWQvGI|i8r;xmmI +z_%1TuF8;58A8IZ_Id6H`=2t`6wZOZxO>6z6 +zG31&9?d2}cRP}@I^hw)`{Hp7I*VA~RG11iN-K+Msl5v05%s#@{s?asHGd45FBsD&Z +zgWq`JXBS+!HK4UGdKN7+Huih)MjiLwy^FCP?AY%rp>yV5a)G7wyNhGrZQCQxgmG#8 +z`>o{YqFfDrb&VB%^x?bF%?_JFz6A2vbaS`aY0 +zO;cK}&UQEJPVb}>z9ZS1XpXg7y!a+k7^_>)S*_9fR(l7UbUvNes>LXH;+2P +z5C6yce~j)q5DhpSXnxUwk9G9lKC*J0a4r3kJ6lRtVc+y5^H3Jud~t4s|NWQl_}i=* +z^segP_B|1w +zqr84oIsLvfc4w#Ghx6O`Xn1y!&SE^}s?eD=PdV&0Mh+*MM;x|urnL_I3Hbo4z2M?J +zkD+c2y08*IL9a308E4Yj$%nCUpJA?hU+UAM!Q&=16nKa82&Ti{a$+DhM|Fl(zNWS8 +zt6`?@v` +zpJMzES5H#h?CL|Z$9{QI6?7u~j9(9}vfiBjMC)yy=&$B)qjPW05pzO&nGq)0Xt;|* +z4{|_uxJhmVp5|9tt$(!S&lu}dzxgBD67KgV*6=`JxtsT#?X6B|4|?QHtamA +zuMMJ1G^`6N}+xOW-6Z6(4qG^nER3Yo@)YhMT%Q=b5>#E&CgA +z9;a^biJfEw21gc7IE2u0#Fj$>5g`wGtZL5bh)P&iWi&);-KFmwxs&D31(NaYSNp?%fHE1n_U|sv)}q2_mutb6AYLB={F>y7^;c?+=rZQ}l*9q9NsJ(!KlpZ6_tY5(EU +zw)lB>baMyAYsK@(QSPVgF=p;l2LG}!pFkm&?E#Z=v1*w~CV8^Bcy_{>rLn3n?+B)f +ze-Aj7*#9NL^w@WayUTQrRb9$lGoNAZJ|Eh_=SO_P!CE#pwL6)0_R7M!wJhzWi|^mV +z{K}W>^+!8q{m;LvHUo*bE1k=~XPp-2^CKOzE`v5+zqw;p@IpTC$hH3;^71Uf-~P5R +z&Q-il^QKt3c`@k`hL}Qp>&K5zm2Z-ACCa{D-6!j1@e41+#-C2Uvp*iQap!6yco|;RAID&;;@}AAg=R14s7(T+}hV{d>`3`oh<(Y_GaOJg$&IroUs&fNpu|FlT= +z;3^I-}@3FC|FO{MFEvHEP +zPj<;cg-@^iXf5sQjtRyuSe$%YZa$!inT7aK#$T47oCd$K>n&Q0i`~hdS9*t#;8Xqy +zmsjvUa&t<@qkXUn9iVhQrMcIn*Ied@I?h{IbKi&|AF}7`T<-Qo#cUVyR(`tT)c3?a +zD>`6rL`^4nC!5kHRZ-3Jz}aIT5~yfn43b*9dcB5&bf1L#q1dR2E`<=X3o^- +zAf7!>aCi7CJL8X$Pio?;cSQG+ll6i**~Iy`LrcIjc@8!s;CX|y(eRPkgq>&R`{`G9 +zCN_~@%F$Y3&eP$3qV-|-lZ}z2=Jb?uW-8~$ZPC=$mg7@xULbPIh)<=yT@A}(4<~=4 +zqn*M&^4XqqNd+r|LY=bm*7S~AohgIO$HIM}zP#)+pkyx})O9a+IX=+uT743*YF$X~ +zk-SsL@p@(Fd_Y#_xf7WI-^WtAm%MO7A8S3ElR)j-oCNO+a{yVsAG~AvzWP2DJ+WI0 +zbZYm3ii?n&h*x#;^46KBkO%5R9X;kx`rJ>9&6#C$pZ%l@-veK3E0Z=SZfaks@3wpk +zd`%R-plzE!>FIYm$%qsCAR{g*;;Y9#ZVdB1h5V5GN%Om72v4^A*oTYf5bdoF-e4+q%H+X1n>95HziqcB7u{aWgLPe*JXisE$RR(t +zJXns_ug~YfdK-Lbt=l|UXO_u>1{#8p +zJMW!Z;V~F>)aIH}UpChiaU^zczx7D?89iES^FYmi*UHp?lk@H?%=fA0q+V1aQ{Nd0 +zW$K&rGWFx9E>l02jLd$MGwvIlajiVgzWX%iSLsF$A&<92)*H#&dpPs9aNcd_ygL@( +z^w*9=3i5X|viBpLbq}25&33Z4Gjaz=N1ie&Kr +zMg}+Joy!&VpC>ze7WgMI?ppU&&L;2mN%y~n-Sbl`w|^$6Ey&?3BD2fNmNyjFl$E{z +zZ=5%`l##h#Iz^fL^)52^!V;PLs_y09vSTkJS3e3}SzhB8@lv*K$r<0t`F3A?UzfA( +zyT`*b@U~;MCp`xZKR)a2E5mb;UCVdD*Fv4Ojag9+TIHX$=Sl2Q+B4*vu##A=#hKQG +z;9Q(kj7@7ohNu? +zh5M1E^IV?^raJ$aiadW)pN&5Ep_lf{J=f0f;I*09YU#`8oW7r!5g&chU89YuykwBg +zEi>R4aUS?5?)~^6v*JqA@aWUSOx4#+gLJ!sM`M%yXNAr|Zx+v67Ed#ZcdeG4b5qpo +zxc9M-xH50w;ZZ>r>poL +zyfXPqFZqS9z+?OQ-mK>%cmrZHfsNiH#?Qb<&1}D@9jv+eV2aP&8PcKeAe;Y +zGWw1ab%mV09S>B@+R1pJ`LLPU?zP7KC0^2w$!krxzHhyin_2L$DAlRFyx}x-iC=)9 +zzXU&jt*BF3oI$6OK0RHc<;Ca{|F7}aLuL5uM~bpqk9w3H5i8qj-mGkUe+hpjSNj|2 +z$zC2rJ}>0MH_?|hb0+VPo~(H?pXkY&KXQ)YE(h<|=)^XXUv?9Evc2fZ-s1jC#iG8! +zS-$H0a8Ey^J)QN#y&GOT`}juo@PV}T9DBUm%L8%}yR|0&#e(0!SBv%u_uj7IZv2f3 +z_55PJPJDY*7rs3>e;333$BO+!|F(}zu?^REC)n;j$@?<)jhm_KtnXeb}C`nIvSNo55KVol4D3=yDdP(V=F-7$E83 +z`qRf#;PwTc7VfofNy-mB^j}%^9T`;rCI?ogjeId} +ziKXc_>`QHlTTELbeJo;q9-7EEUe#je$|p-c4VpLEz;5A@kCtL!WnY!wRTHqvk5ayZ +zem|3(&u8;X)#e8yh}*m}yf1fH-*BIAR=c+o$NzaVcWB!8hQ5r=nELXA-$1=4>gj&8 +zCiF6jm0gaH^Za9xc(5**S{!#?mN*jnkqJMH3Hbnj{7f72K^uIr4I4{a{N`9&oN=LV +z-sZ(*duG3bZzi0-NY%dWHqOcF^PxxhskOEF2TW4-L*+Bt%%|+2>W5rM$=q4GpTX4l +z{qaHhL1di#$*eDQt|(`-rxtj#v+pSGY;7d6AU{7|%|PN925}cJxRpIn{_)DG@N}-# +z+mLSaYQTs3T>o$|^*|f60<6noSsQyIe^d+4Tx*y&o&a>ph)m^@3$V?E%(>`qsRp=>2I_O+-G6Fh-UVSCP5J_6n(sco?vgDibAn%qo9kFfm)3OYDZy&#iGP3#4FI<{sAG~Nx!Z8x*grEc&OFh32obmMUs}L +z)2AOdasR$nZ^fLpLR;&f3Z`BmJ<9iksb|sWc|0G0F3;up4=>~)2X5nTX~y0c{9KdA +zk$(v>1(#wc?fN_TKdk%ZFJoO?dSboxKMkg~=l2+`h229#pJMq?I2x5+$F7U7eQA=; +z1?wM&o`-g`CdfV0XhQyVKR61;2DNrPuXYsrUw3<(C)n?BuygNi>6i+?<6lrZCinaL +zdpo9-qhryzNEw +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 +z&@TPNon7qGqVb;$+j&Dp1a +z>|nt@{gbY+d_BBlqlG@KefsS1PDiyB3_RB9UK+tD90$J(ZMnfGur&+*{C!b{_xP%d +zw-orwu6Ju^K-;!W?!D3f!B5^T+R{D}DcI6n4$vjB(9S46zL{}LE|ok~107i24Sk4j +zYcCW`lF|LqCS~n^(&fg=+yAO)gR<5hDLZ8Df19NAVe9W5n_1%aUy)P&B?5p1F%8D>9&B4}8|AK2PcfQIdu6qI(S$lYR2i`_-C0`qV3jNmeEZ>!Q +zGcqi?0Y8zJR&a8INp4~Bl_+?3w8xf|ZOhjq7J_oMw| +zB$aul^W6~4Rh;>ZGmo05cxg;Rsb9_}cu972(Jx1^JHL`9WZFT{r0i)M;5&kE>jLsC +zYyRO$Rq&)Hc#_JuJTU}clBBfF;8^4KXVwkS-cNiF=mZ#!0nO3eP9E*2dmRP +zh~#d4pfc(C%Zq$yZe9kf%HMvQt9_%i5BJG>NBYWG8WoT#iTDmS0FvX4}e8-?+PCEh1`fjJy0dM(b-FSpT(Kt{S~SwT=oGL%}WL6P5mZ2srso6;9K9Z|-u +z57zK9#;$ldt>53${x!g%^}IM;T+gC;ofF^TQGaVDnYyF@%gomQI;Z0&>rI+&8s53o +zG#o~!J?!8hn?qk`GzZU`9J>F^iEEes$7tQg^7=i=11s47O2?;u^hjQC`ai8-t!>E; +zdUppts;X0JTXA*NX4AFNq73E37Z~qNz^?KY_=w1cpz?kkJ!k&6H0|5pEYvO$&FoR(%f+Yw}Eklp*4U)Nj!ovYHJh!w|$?d +z_+im|QJ2;UmQnQ0I;67Tl{sNzhj)+=+E)h(zBQQjq(M#&+Yf6ytv$Z(X7^q_Fdt5 +zKl`j`cX7<-54U_!zX@l;t!zvBe<-{_%6G-WFCG~n(caAUUoHCbHi&Ng|I_AX!!$CIZ;e7q%(HvWDPJehql +z8SXXm-_t#oOIho;nDE|8?x9R@4`pIm62H9|{(3q5^|IK*!0FHK<30@9zA^|r|A!{I +zWs+&oxX!zmv+CW;y|c5+y${5F@0?Z3z4af*M+;d@_hTLIll9PNSzoW?{}n70oolX~ +zY-Q>AlA>O}3K?o`Wu)%@W>dFrNhlBK&H+2Goac@YAfL-Qk(tNeANJ8yVd9O%Gpe8U +zhl1(D$mg#9)_*6Me*C+^^*P{>KVIp5myDV7BffYseDMr<2%v4oi7XTP;sqtJ>&z#7 +zF3Lh%@E_^Nnvcdz(~=mvKy0g=!}&~XZ1uf8=r+*jPgmJJOM>eytT&jM$FB=!$wot6 +zE1SZTiTBBRYOB5D6Nwh~W7TQ?ZE%&~mu+hrv8itD9YzOafB#_7&$AQ$wijbBtB^z2 +zzo+xPVmjY-#q)+(GU{YD(YKRNMN5`H0Gr0G=iyJ8I??rFesgO{bN}#%&4SI?5yY=l +zuE3W|WE<)f_M{kVvh4gPi+(j#&_=1eCVRZ@xzU;sTJ$$ZwNbRV2z +zZHKZZ*YNv+R|i@A)zHQ?d@(deU}aB($0ft_sAO8Z?tSnHt;E2k<9RBtr+^pw?#pB6 +z{Js*r_#IvgV7( +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 +zf&QTnlW;CvROb5=#fycf +ze`4R?&3X`g{s@!mgx6GvR~zrKkla^{_k_NlS8PIuw<2z8@L^6Y^_4>?Q;8p9Wd{m$ceHxHs|`76t}Z4JJh4?v6SE}CF{yPAlx +z*^uW+Tk`Ao@VD^$Is@OSKL%G}tMX#+Gs)n`#FORU55=bz0cBsNl- +zj3>Ut$0ozsd|9&SqixS$SVO8o@RpAt*?vKQ4!bI=}v>=kz^?x +zJ=!3!VZ}PIi4BXU&Vnwtdm(-JN4%u`Erk<&EUoX8@>$PKw|Yxst=>9tApW8IMAAM_ +zh9?aj!b_2nERCH@ea-WhXx5v?+P^8gJn=L91k*mUZ6=g))&5-8)(qY^#UcxkA0)$h +zb$suW4*iZS-=e(AE;eDFVf`j~QG2(1s?IjmLvGCy(^29#_l;aDIaKfu9gJQ-eVZ-2 +zJx_O>$!o+ncJN((bxU)s4by1*82UnRmE2X;sDohEl+bKDV!9&h4cOVn(@M4^U7twypa$|AyN$}(H_UuP5rGA26miYRZQ_#b`e7s=u63@20 +zh}f{9oO=V}3&e9AZ?nG*4dZn+mv&qk_Alf}s|Twu?`L)X;G+HuwQnc8tn^>jZvp#A +z&76>Cv^M0gARh&-E$gSSp^Tpbe)k1Gg`WDjHt(lEyH?*-TjHlMJ@jF6eFstUX_Smv +zW3>JVUkPCg_K}aH%X`5a1flO%!2J%+*U$O$z6g!UpLYp#yEKP?6ErHj#?8?4Eq*p3 +z9gO;s+-Z;ztB&2}9Ud^v-0vsNaNe!?LZktoV((`5%s>2Lkl9%^#mcv+uo^1hy)}bF +zxulB!8<`jJ?xO>y7-ZsvwLw6Sjn%87@)cf^4%g5M%BW8tox!4Xn9Fh#XSm-YD+&(v +ze-z*PwF%R3^nBz;+8*O_D$~D{UtQVZ^cBnxYDd$q*1OuS5?+uiOJxE}U+m9w+0QiA +z#=oHFt4Ml^2eA5Ac>LlRJm0|cbND1>*>|8Z@Ko@1-*|4;+uVPeSp#hSfpsJQZ{}WS +z!6@0^;m5%!ya*Q+;GwA=J|iDQ_J8p*2dl=x80@%%H669{^ZV^JjK%7RO@97AgIo&V +zarNvNzo~QMG4IxNoAtTq@gBkCHe|1D>_y}nBiGcD82QEw`N(qQlFPQS7m;twZ#(^a +z21it;+AlWa{K*wb-Jjb$xuQ<|NAvJqXvp8)C;2_}ja4Qxey#uZk7sh10U$t>}2IXZN82V~O9l21(J$9~dW3+Z3pAv0CCjQO2)67Kj +znjb$mJd7N21N3|&bdAm+ +z+<&s+UZin1WLx9BvvF3Gi{JBP--bdx>fA^jm77bs8z{&3_?P|G_?T~nG}QR133i>i +zKE9kUueNTaJm2Ft(%;ZO^{tEl{RDHyD}C!e30z}&-V6L1v-|~ye$v=6Kip-^I~enu +zJfq8iQhKdIHNzV8{)ubJxvYup77mV{DaZ(dBw=V_L=NrWlGr#BN$BGKsj&%d~?3_ys +z1MihHv3Yy7dGiT!-cYX{m=ssn{JK|n&(qNbD|euao>AG*UOmMuqRf}j6a5hV&`$iL +z#?7m&8#^NKW{lvjH{kj#cwKp|X&C=X(rc>BMlBEef=NCI&1a@;AJ;OX)oaC1=0WO9 +zkF}SlbwrSOa7qwwox*25pY?n$=W{uqb9W2SKbEY +z?ApLw&r4%3AB1l2-=hr=aK@};ER8J_Odrl&*XOc{FK40SOqjE4K{}gQm}F0hh55v8 +z@UwBg$N4=@nK)(R)QJxr8Lhh}mW@9Qf6zV)lsM>6L +zB3k!*@l)nrb|cBsO*fdjyNG}MH8jKAc!%Hz8=oF#{shfb6Yq8YZ6QC{G|Vh`6JC&G +zT@X+1ZQL=;zTdK~+B^VFu7f_CT7s(#cfARI>C$u#uy&UZy=!AOgMIJRy0R;QW7XK` +z>{ah_&lC5}RmI4~{R%mcfO|Xd91c2Y`;){=C_k}y;LiO+>^W5LyW%W(uA|nYb=kI=^ip4DY&{6{4;{$KEqALVKMplS8~D;6YvG$n}tSCY?qKGS?I +z=hNr&K|V8lw(^*j(o?^#2I_a834zs0cjs5h6j29LLUgn0cenbx>s7j}y$ +zGL9cH4m$?P#9d^r4~!|z#t+84Ax=*|(VySpN& +z)n2WATKnz|z(7wy};{H6uG}t_-$aD8BIdXk)#gSU=$HDp|wW6&bsZVnM +zi4GiGt7zN8Rz?^0DCO+C537WevJ9 +z_xpiMS%>H~*{8UR1Y1)AJH&0*8~OQ2&Qol%|B)|E5)A6w^{e@l-Ys|m+4of1C05_H +z+jwQaLVJzKKBaBCGHScKa#gG~?5JLU-waui1gF?n1VhUOx-U9^|JRiKcw*Q>fxVqE +z9q?YZcrP7?!-K}tQ#m(A;Yd1S<;P!X{?n|2cfIyiGy7n28vDL^zhDwwrVLF3rsWZ@rZh1dF2=hX<8ASs6#GmcAQ`wyZ|_^Cv-1cDx~-xv^~q*De01 +z3;m0Zy5i!1@D9IJ9o?bhuCc0_oLiH +zYw$T6zm=HkdU7GWGzh`Qk*^Rg}Fu&-yIG07KV +z*~H%Z2_`qvB;Vp3D;j?edf&r-b0{xU-OYYe#ko##xWE%{qA%KnM!AC(9yE>hxj08$ +zO9q_{|1a}7KO(aR13y$-_3ys7@>v6H`yTUbyzDsLeW5!s@^o1?x0IW&elLbTO_hzs +zInx=lhDY-4eCSuW=W`6-)_asrz@=oGp91K +z{;Rq(3m&rOe_bK?0`%D>_P!#&VoVj;+dZv4mDBlKYf%4dtyo>K#sZDR#B=??YY%Q6 +zBK+V3kr2L`BF{usr-{5pjl{1x+s6Kp&sthP*pZALx$w?J?gH`8<@Pt>stGx1|EoVw +z>?gNoyZ5Zx>ejEquEiUQF?epi)bGPQ2gtc6m;}#$?gbJ2j%J#kjg0d@QsO^@+$Q_+ +zfsy_=@sh?7JL5+#Z37-NhWiNO(mz)0dsg?0*gHrB*P7O6HD2^2c{~{ILGr`3IzAfO +zisfIRJ2-9534F5Z|6lgr1w5+y&i_9%lZ1;2go_F)I!M5CD0pe>itV~Rn6cDdP&Dp} +ziX{jrmHm7RTP_YDYny=s~TZzmt!D9+&WKtE{W3@+~yXYd|1G;&5Cj4c3|^*UnJ7%Te!ASR>RJe +z{jTWfr~egQ`autQf3X|n;pDwqZ%IdOSK?eW2i5M)$2E-iJNe-$t|5aCQ+qb4zz=WZ +zWkF1e$-{YBXFt3ad{fl!`suW<_y&C26^Ep@{68E)&JAOQvx`@-OH8yL&R +zK32_c{_p<$;Bo0b+4!nAI_KD%kquz2h<9fJI~rF6BmB1M>lFV-(vJnXJPZ4Nl0KL7 +zu}dNb-hEiV#E1F^G_Q2t%r4eD3HA(nps5d4edKT-SChSeoKxp +z;}N_-i*u|Se9JcUX6)hgCZaWl&On1iXLeon5_uQ8p|il5`cj`!AHj3hDO~SFj|*w> +zj~LSyJ|1@E^!+DV`2VC<-#^UKJVeW*z4pp2SAOf7gRY4li@urtW;_v{i)g6gC06ik +zp-iXu5I!Mm0yea +zkhcS${jn(W)5uNSlmAzbbgthr^kV2qUgdnPc9maMwlCSZ6dPPu-DqbVD<%2)J8RML +z@PEbdAm8O*iW*HWh4qv2fP+wGhOnvB_r8=ClEAx)cJ2vmwykql@%{w;l*tccE{5n=(U*_G(g)pVK +zO64G{4fp!SWRUA`q@|p8o$cxBcV=~18)ThTvnUzX1*y(DU*`E?_$8hAbI;U}X^C4l +zz6-7o{V)Ct{w87jcOM*J{T+O4Ti+nBWDWjCCER8FV=rQMQc__xw_R=FtY>(2%4NA#-rA^dO_1bd?A^_<3_XEl!K +zxwOZ37hax`{2K7=n;64FH}Ky!a@wCPS2$Bk8_)1xG*$ET9)`976w>e?o7b`OEI$e#DP-pFZtHNoem3W7{|UISGG?V4(Mi +zz=o*%^4~pnMmBys_F&oMM6b%AZStX#>>k_gi+SiZOX%VWz2n5`KdVTN6#O+ +zlbW^YbuIwUcEoN^NY{0$WgV0Dze1jeYphAfTeG*FF%(^voAB_(x*wb2L2|4QJj$vV +zczbMSIeRW%oBRhWwYZlTU*L0Ahu28%5RWdTr5azZkCnQI9FclfKE(@O^{*(yhA@Wl +z@75gfZP`|A*$u$a4nAvs=T~lwS$0b+(bUiTRj+bw!9)HPC9I2N1<@I`TgEtQh<(4G +z+==od&hs4RTNBDiD|l8gDLGT`)Bxk&_2uJw1DB=C$i;K?c@}V1Qv|#Sj?+hD`$jiV +zwhVZtKha>lS6bx7kH=0>L+ux>>zal`6XZ`;n2VPEwb@^r{k7R&oBg%fUvMcn!`%L@ +z0G?aqM~JU_YXyFUU&KB^+ojk{ivJD!*qQiO&c=`MQR;%+n_A`uls1 +zaEAC}z~43Q2>yG5?e1VWdao}<2RR?)`_5HKto0`jeb^m77XnZu3=b;rL +z4~@njjeX76I%))J4r~72pO9j0v_{og)*vU_cDN3?a2#QV))mi~>k}uIMS?Yu>4EidZ%gjg~_zr&NVIS!h +z&d~1-R9=ci`uaiEA3qpmt)K?VEbgms^&9=)N}W&PUG%$ftY`78|K&p_SHI?E#>>1l +z7JqTiW7e|~?>-iqgB>vbmp3h`RyIgNBQg2$E|#H +zM!=8HmN1d{T-$l?ZogZs5(9}uzkb1^1o_e0-CaLu&)Q0aAj$zFb +zf5Ob@dUxZvjdL>c=8^LEvL42+eG7Cpk~5=R*wb07==`^cJy^^h=p3kdWRh|BY5r^N +zv{$(u#MmHPw)p*zS?$DX#!x$?6kW^8SexB~p19>PX!Q12N_EMKz=f_g$=ZG~AgIeh +zt&Y!Bmuzf2rM`CK7jF6+-e&&_o%uWG69+RSKDCT{g2~&*x7ja@jMwyLEM?sPfS8** +z*0$NLCsPxsvCZbb^TGKijGM<=m*e*@osu{GEQe&&IRpuJulO2{Ibj +zq|26mb`0~fzED2yZSJw(qgcCqT+KrEk@d4#Kb!S4IylyC^2bZhvliitCKyl~YqlS% +z)OT-f%snXE*Y(M9Yn~3S>Ap8S=B9N2!?=6jb;)tngIII$=e{Me*^53m-WvHg^zXFq +z{d>$EJEwG9-FIVCYEBw&Z4e)34Njed4j%pdYI06~iDxHO;!ll_`55*|b4icSnYz@U +zH1;ICssvn-T+-E|7G13mA*+K~q( +zpJR1Q$1_nI&x7Av>7)4cj(g_)+sOYP;+u2^%DEK1BU{Ba+%xZ?2af2PuIc<4(QfUH +zKj%=@SZH;_@KuSi=syR#$a3I+E!X;@PanMBi}#sKZYB0tdXnB&ZTz2>y4Jsr8E#$3 +z{QGfl0RK1kdH0kJ1KvHQ9C-aPv1J#ZOYC0krFaegKXZ!5$J1j6S^w04zGUpt*1w{! +zHUHc7e~|UB8-nX;VqezBT22{st2O1N`~CT6Y{gHaFZMZPrj>p0GwbIj_G}quslTrM +z$ls`CiA#Rx;f$r_lzR0+UbcGmarPjq{u%nvZ*-wMz`NblNL7EQa!-A37(l=El6RNH +z*T>#Hr4;?&dghd2PJ(64$v>;zta(wm?tU-w?FF=_lg*fWaVA$+;1L6Xfx0IZtviIt+d@h+n&bn;B@kDU#_%Fn!96v2ylbsMVwXBD_*5G6Koc)lO`2O#x!CCo2{2t===xp+k +zLFjBAB8Ht<5PzRvX<=JwS@fFaZLw0hljAc_swS5{u^LtdKK{_Y`pOru(TuSkn0~vd +zooAlChiCW2X6`w3VPa4FFso(spRDv{W3760fa%H??DnO%kVC56dUdQ-@q_35Y3CK- +zukLqk*WchzP^_I98+Cy<^SsV8%1!iHa%H8V@BJ8i8~xXhw5FJTM##oA##%kzbJU0G +z@*U3__^%vN%%Z(~L_iDmuFl^&lbyuc4dYYCy7{c3{Kp>HOZ_?Edrf=6I{wJ2Ifiw7 +zJzU2ftYen7$^PD&c^vCFG+f7>tm8`7aR=jgm37QsWx3|rxjehUnz@5@-0|08)=t)O +z&$q@}yI99pnM3VU<<|GduoKW;_QC$$)Bdzsl9fVS*0ru}zy1?{!Vd16wY*?3 +zNsrVZ9Ex!k^Rmv9$hdX*-GM7QpW){h);^t+fndY0c?_(c6JN(OyuEWhQt?AVbXymtwGv!-7Q +z`&k{^W3`>g*$zLlHsmhpYQ(c5{-ZI`uC4LVu1$Z3<;Fjj_O)&S4GQYo2-n-ddHK2s +z=iBf#ZmMo{&|x~i;P){0QTuQLA9tDMPFxJmE+lpb +zIGxD&=BYL!Fjv=pVWOdNn3ZpN1>4_<4MpoZ+;TI+tkk{2)h`^X(wV?N%dZ-u|Cb)BGS`U{&>1hC +zdqL+z_}Pm(w>f&YjW~q1e&<`eR=8HJ#|NK5o%^Jd)?A9;dckg6>hjEZQ_Di|uj@rz +z_weJ;_c7SfbuL_u57yAPUT}_0yy%odAENW&k@VHI%v0k~e^1e_7wUv_=gO8!Kc@t` +z>HR081LvB~b3AX(xHG)ao{Qd0V^IG+J(rhT!1L1k2U@~w>7ke7*DTxyFAaTpm22Rs +z;q%d4D=HOl5zJrwNd4h3?~dX6-B+G4PIyflop4+9C24d^p)VWl*5dOR$w}dOF4@)8 +zXyljtZ~PIo4*B2lF25h-oKblHTz(G;e8-TXM(MrCj^0%k5`C3?vMSUYNCqpz=UI0B +zft(@b10gv~V-)OOOy1x#h#rh`=O|b3a`FeSBv0h`$Sqm_B0dtcEw}prvfM#DAB=gy +zxX71aFgbmGhA+Y30^G^xw`}kyRNrZ(G7l?Xoi)n4A%G?Goi+={&U#N)`-8}{`O5Zk +zD>pRA8MuSIn)Ar%HAuXf*p@x`bk5#-|xYBMV*r`}baRLw*Ai+3XzE5Bu7AKEMB +z6OungG3^zhTjuW)>E6xtRZ9|zugYKN+!NUwqxI7BYSZu;_9EJc@8~=DCpZ`W3FdRx +zSt*^>N)xh40vqg!u{prU)K0Wl#{TV)cY^0+3o*VnSG{EFYs=RrP21vs;(NjY;YXyK +zF|Yuh&|Y5uqjRGs$i; +zFf?GH8}RlB|Fu6evLD57%x!k$W2t?;DZ80-3UR)~_Abn9CLVgTv$&cVUzZr)Br(1g +zF}}HGoh1wp5p7(5Mto|Ty~WlhIu+MErE@%@{`ucxHPTlhlR9H~4qs-YgT}8P|1fLR +zTx166;E=7bfmp{WPDgsTq4f3bOrU$ajhgnvPQ;&SwWbQj?mHtkmATqptL1J%wh^59 +z7w-KR?~j&yD{_Fb(>xmF(oifl=MK9jM~ybtN$^n1n4cpyPqjX)T|U)(yrt-j^*dqU +zEC|$XxZ}8M?ag`_T2}LNk2L$(fiR8tzOV% +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 +z=$)`;cTD+$3!JQ>ekBGs4MxuL#Zu +zFN|K^O6_5t4bpz4YG+EW7GI$*u&Kvn&X;%lm34oGhs=V1pqGt!qToyM!x5h|zaI*J +zzu#nFO8Jh=^Y8<6fARjRjmYQ`|MKe&O<0E(`qKc*x1m3fcaNG30ANO%2b56>HG`aOMxc`n~CzP?5- +zShhFF*YM%e;0UV^uuHJWhxH +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 +zXYS+c7CrBO@Ih4rJflB6Va2a +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 +zeYV-TF4yeLvo|j(^&iZKCIWUm@8U5 +zlf1_Ba!q#2Jtea@mswM4bH1)QttV&W|8ec1IW_F(rMz?d(4(fzg=UrxmrrwZysqx3 +zDP`cpy}(A@lB1^7(1zdZP?h@d|LIUwk9d&noQJ~1Vn5fBhoWmNcI1m1;i_~-J>tRd +zOH!L|{}-ks&AP^GcCOAeJ2SJ*&J8)>4A|-e9tgJj0w-g@ +zhcD9hUBK2|z}92H*2O;|fy%%VS1_e~2I6Zaz*Z5k)hmQ8^V|=3j$n-RJ-`<5cvlEp +z&iHKnyZ=sZ${%%!TV7k>yLi{9@Ll|77vIHegScs6HR+&8gBUCxZrS@G0@*rLYSI|+mSb_$3BPmGOTf_zIA%Dy?IHq{rvc5 +z``2rm?O!!E+b_S-OnmcZdj~XjxoBxMcmVthc4vCc_@)5&8Q?w(ea%5%f&Y2X;F%$P +z6|JmCCSAq+UIGVR0tePVg$x7T^wt&S>FZ$Hi|Fg%5C_b2FZ0}Yi`*U1*B#K;mqHw< +z<;F*xuLK6vH$1P%LmS{d_bU>-l4-fTa%q}hIWe6#)N+GhKa#%6ot8~ENckA`p_ +zH&h4nP`?X2@YiMh8OEP&cIM{-9x<1BEC}bJF4u-o?Ikt;c?4pjTPun`7VDtG>{x +zdEiJ)^Mh8UXnQmB+syoa#y;J(f^q*{+%+_c_GIVi#r#T`U!QP(=D8p8+;MSt#{)Lg% +zrvnc+Fjn!Tqk!WgovGO8ncC+D_W395-&a3jpY@#fd34;J!#>YppJ%eqv}>0G$E%Qc +zOdXH@ZB@dn!OUj|_#wE}d>WWfcW`?K^AXHyK7v`z=X%DgIX-&yyNAPV2(N>gM+x&- +z@sHM&6<@V#Dt?7-xt8($)^ZJ;(w6vjAKH-8GyJOV=q==o+&67*4&CL@tybN)_ECkNxW$5YC1VSIx6tMhVG0-$jVWg=cM)@) +zzTQpfJ$#B17yrVw8n*c6{dbDo_*eg~+`1n4p9B2Q2L9&*|2F`uvqD(qx6OB(Yc}_7 +zp0jyAfZhMvTUm+^ReI;%X|w)w@3a+PC0ABwba!y&IZ +zbmn2s-)hJEdukc-%;ZYqM#;OnoBKPs-|tJM;|ibe_xTgX)#SF=7mn~8j~G;ZCr+7} +zBTnM}_-N^eG&Z$2(`&T#-@otOsz~nWbUv8aA$LSMJmnvh_YF!O?gOOu(5;NJrV%%f +z{zkutGM{9n`*u?`_FFgb +z$1(a~)=8-GgHF}3S`-^@q4ByXIl5i+Vy-yz+cHJv*4I}Kj0+3Qcx?`K)}vx(9A(rK2- +z9jzLM-LCWI4xe+)QMwNcTlZ@Ii^rsqW7KA@pXF*jbLg(boAiBp4!=$2=q1rTWxKa) +zvj(Fgzh24xN&MWjHaBIAKW1EOBflH)dMRBJ=WT~zd0^{+-RR>m0K01(5U4XQ3EQOwb$+66ko?Wud~KlwMU0A +zT}}OYo|{*V91l!y1g7`I##%eiDS&DHKI4RO>z26a20UjbZDHHKRO5^K(mE8*Kbo(` +zARoi1zQbzPBC6NWeigY!&IN|7Aiwx8sAsVQUE|GK1L&6Wjz{$#ZmTBF7Cq&&tkWO) +zNKg4Ndb@4-xcf_q9|V?t-rvXj+kSyf2N`1fe+&!Gfb3OS-;R11J>{pGpA2LL{@dD< +z>~&~hF;P`FIkOVG8^b6m7nWj+G(Yq=YT!c0DhY_`ZL$m&n~`4eQJ!V +z7wCNvAKxr~UE$c3r<3pYIuD;|56aUp7h76nBCFsz{JGrJtvN +zhvUgH9@T5o9BMM;2WUd4I9{|r*f(TQqqE)x?6f?XC^NmSR8lmgz_$J{bL+{ru5p34jyHxHr}T?WK3|_~5#wF#0h5g378h8= +zhOPDwz(-1* +zs%Jcs@kY6=D)=7ZjBL$yqQ@cJuYW`N7g-Bnf1wrRpIVd)>?PO^I@wA@51!=nTRtnF +z9$?j9X-#>gw^bp1yW~2nw>5d?`PBYGCfH6L<1}l8>|61Oaz<3M=IpKZoPIvhK2enQ +z3_f_1*|Y1ij(E1tC?0;$lbRcCkG)L2)oAK10%y+s)C{U;{k^pTo!s`eRdZ#c$^HR* +z^Bi<>6Zcv;dWkN!7Ut~R670==Va~qA_;)#*{uJxWzzxUa1TdA*LyEA(~ +zqtThRjJ2!AQQ=l63l``ONZG6vPfQ{ENgkew*kigK?IkL)Pl%Hqu7Iag-F +z!?Ht=!^e4X;j+du(*@7Qss8h4kHtP7o>znYwjSA2wl4W|NPj6m(1s;T6SD2e7j!#1 +z1o_`1YdMi^OTM7e1sXqmd=N7ZwVPN!;}gnRO8!3RpYl1+FC-U8Cx4&q@u|pNMlYxN +zM6|S&c&gH$$7c@3Zl*p*ebcWPxvbsr#bhFD>X?nZ!mrTtm-h-_OuvQqg>9U@EE}Kr +zyg#F?_mVj0HRm|?V<^v*-fYbTFXAUKSJj)4O+q@~-6O1uUi@Ci?-Ks2t?V$%jm}~} +zQ#9@<_x~O2rSdGA+*h;OD`opuE$q6dgS=0f +zTddT4jf1|G`@a=9*ZTG7$8=>EKc-#K5a1-=lp$Dy~hE}-HiX^$2 +za`;AMvrgtL=s^y?orOPS;M*R2yBhi3B`-sgybKn38FI+)S@|pnc^N{P&Bm4-|2^v@ +zndWIeZG2`iA84L~JZa?By6Ttg(zoy%VSVSiMh0|5O9V5bC(y-F6S&uhIrru>itojI +zBAGg!%-YH!axb5Vp4^Xoq@01K7R{AmOixHh>I>}TE4$js|3sX{iK#>z9}j$;_&KYh +zZdeN1<&t}e{OX@S+Pd^1&zW=*bcKAus)xJ&Olyk9sWZ3sUe_YOO5yldoB18$s(81~ +z3yKw*IO4O#3Ps~qtk5dP-BYZP)>7-Ym~qv>i!?5sSE6xgJn7+$W-KdMH^s0-?+DhC +z$i1Q=M~W5N$n#OG(4&R1LJ_SFebD8La3QfmooF@qwgx%KQ+~P7?^|o3{@$Zq?OFLD +zVudC}KIr8pF2mS-3SxyW=&284h18yDm$v+m3-Aixa^X*^GLXIeR}WR`Ir$A5pYxsg +z{|RS?|Nj_gRM$&#`=`N~?Vk>3j))_`-~TuqA)f626F73^eEy!iGu(smg~?`TD71VGbm&Ix8Ld3K8o#b@d(F? +z!v4y`{szf!{f1Q#OIE&D(J(U +z)wyr~ls3O{dSkqXb4V1|`yH#Mb$%XkK{o`RWgl0WxipeD-8q?q01tmjJPySvD>Q@=foqx^XwBYREK +zb1fK0?19NiroH`Qm%ZH$uWMm0uPYv4UawT<$GuE_8^M!cscXK(PJIJA>ic`@n{mkg +zmATnU$p-ckcJ$o8B~nqnE!o@mP!CKs2UjXDj-H(o)RoymZLr54`FH}$oQJS0?BZ>k +zqx?(Ay93#S$MCVqE>{h%ATD|manZ`<=>KbwUs`9qeqTD;)E?AXHah>E$~E~csm^S4 +zE&trB2Myj#`^}*VJ;vqytb>nlm)-bB#7Q!aX`}p}-z(~JCT?S_sAYj`&cI +ze2=_PMlQcHp3)j=eG2)4&JluN(Qxrp(ewAAwP)Z{_4>N~`Sb89Xx7Cg$krz&Qc(@O +z9{XL9n5uTwzS{Du@X2BhuiVjj4(0IQcbfx0D8b%f&h%+`xOiLb(#E~A +zM9SzQIL|Am*}NRNuCnBLFW`6l#&0yJt6fT+zgO5xGe`Ki=4j@3=Kf0Ke-PF@{wDLw +z4x}N6q736SHK-R*1Id4{~a +zg1RZ`!PeAb<~fqODa8f6JpD*G&!O>Dlv`|bIM3_5%#+_{o}$BJsHO62<|&y%@`L89 +zxvH+BWQy0HXsZ+-I79P=7Tu-!o`bI|W81-e?>JAg!Gdv{$!l%KmcoC7JZqiC_HfM9 +zYupB(HT4>=Aio-CP{D>jAKwzbYaRVp_L-bl>cc;)?TGPfqKBIfepDIYXP6&=nj5=5 +zPmG-Pij~Lb2_JRJWvBI!UO}<||80NS{;CKjLKUo&IVI +z#$&FpCjU2UX4dufy;bRGy=Mg9{VVv-eZQIUanJw5hgCDI_V|s+*f$|xFGRjx8a{CM?Bm}t~B&3EAg>=SGFkNsq}()%_DDQ?e~WVzI6kz +zQH(h^Uegcz&#BK0BVmgdALQa|k6rwgKIb9h;a~UkAZy;2@UKH=>gr#&Ad_{j_n;xw +zS!ccr9Z6=LA22_Sh3huIZLZtgw|Umq`X=9xrS62c)MI;Dzc%YU)=0jhH_-QE<2E*f +z9JG@6%Vw*Vx|>*(Lx;tokgV@AxkCRVx5mDmcdz<%&Am7eo9HufUc!~fBrF0J9& +z)LYD-Io>}VU0oTrXJC3gwjueE+>&gJ-)uF;t+X}yUz)S_{t?;uZ~g=S0@h*Me}%S? +zCjwi@K-QrZKf}jZhq@OBT0g)RHtFvMS+8LWd#%70wwb=?F>j5T|ABwNzgel%IRD5l +zcGfpr^Lw}ELJct@uh$akg>a?Z#XcLRIqPdHR{ +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 +zyWWY+URVJ6*$H1GY~`H8f;2G# +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 +zTk^L=o5|l8H_`v++0bzMgoR$^ZVS +z*Wi-;?eU1*8y`adJ3^ZMjkvvmTnQ!*gN&;78{?TLTX`Y)8|OM0^E?lGF9mxKuybnz +zH2+7~vr^W64RrL8ZuV3M_!#_Ul5fQGG3cz6b*_5N;A7z5AEHgtf@!ef4){|S`>N64 +zS*p!--SDj2KxemsXQ}7NvnsmaS*UN;YV>({3*zGbs_!eFlOUa+q4w3Y;7gW$W%4D| +zOO^C}s1_Z21?1Az9x>p0v=vAD4zzT5U&NS5w}!si;WhhC7kM-GcgQ`h{SmzAx(u=3 +z*q76qz(9ttf{d3 +z)X%mRkT1#D7VxCz#~^behKYLOdgxnY+OW^yS89T7Gz&JTz1VZD_&6uf7aB@y#a`s^ +zmLc{z>me_hzmxGB`jq**!!~C<+)Jiq)IM{E-_J3NWtoArk +z&aQW~4u;(d?WX`2`FBoH*nPzQftU`w%mrS~1YV*IH^+Gi#>R2HYs2{g=vQN5(>RE; +z!0S`Rh_%`1gJX`^JcMV=xMzzw>ydiE9M@$09&GuIoH;c^Ab+EO+WBhJ!CQYAYtIe6 +zFMOAyKPT*ETVV(8Np9WdM*D;l+S)b*-w7jrN6jb+AAWy7lCQ>1JmdYAMs2PfC+|Om +z?;In)->uD+kaD{DW)F5NOqYbwP{N4a~g5ITTkT=(pcMq{id-aYK-A1PD)1iP(!r-dD;B7W7 +zCmlS9u+VVMH-0YKtr0)zlR%C-1q-=uZk){m9JQ&DoDGn*Wxrm$Z@`PsXju_2&w{>< +z_d|Ete1zWy&=bN!wlP^>d+p3f&Z<6<9N7kPgmB%pT@gQRUZi1nUhl}e6n(9FM9Ucf +zU&nxV?0Mt*PKJ#ihxuWjg6=)A68^#dXY24^jJ@3-r7B>9NauJ4pgq;6R*gB|-{Iem +zb~oaadZi<89NHcV8pnDtNA^YX$D-|Vz|j=6-P(Z<@CkT0Fa`Uq8DsB{_M0D#EF#Pr +z;13{t6>RHvbVwV}otSgMR)_Qp>~LD{-x2Z3dvEH#fgR&4_evw)4TSX=n@=n0$e9A% +zP(FgK^buU!;a4~);k&QhE7xYL-A8=f06T&?&qr}4op7&l_*VV2J!d-FYK0x46?TMm +z6VcW^?Ggqb0|seLHXR0lFJZ8u9=|Q{mG(sod^ZrjH`^AjgG?1Op6qrnVNIGx_|i{s +z_Ew>{eU9Gt;(l5_+rE_WHSCLL1GX~(+oWmwzRgAZN$*4!jR7vl_)liHOZX6Gv|SFp +zy4~Ao^z#^Omzh|{U69|I%Q^X}NPZ^zA+2e|8qUO8sx@pteJie4GWuz_SMNt_Yx8ql +zq?;U97N19+_9W6+JX<##y2JGd)&jq2hVGDbb)?({+Wai=Jf4P-W-I+yKsM$$h))~` +zaf&f0jH{6C4%XY9YP8#MCiny7IEl9gJ&|j@vt8~p`s(BNk=D_Xv+CIs&|BK&9Mrx@ +z!G7qEbt6t_Yuj_~!uU6!pH_^&|BdbD_-O;8o@`xnzMFz~LEpvDv)Xei@$O>23mvfk +zi8d*Rs(r#eBKHdB)yjAk_IF2HP8Qx7i+AXwYF>tSAV2&F>qVTqYr8G)i&(GF_ies3 +ztXCiOlUAnVU7E446M+|7{s;L=jD7uc`1sa;4R|*Uct`$(ek5$3KkhvQT;CNw?tRQ? +zpLjUy?;`J!hU58!hr}@p4im@v|E+z|I>_kS_l`&L^)>@vzt%4I!s1Eo5?_f&5{J-M +z%GVfEXy7c`k@$LEyN<8$1IFz4hmIRIVatB|hSA6MdLJ7K^gc+-XzS_`4|lXlJe&f! +z9>F?pcnEM^(IMaA`{i(BY|GIWecA~( +zOuWK6$Kcg+w2v5uuH+l|GDl&r$b9U-1a8xp_bEO+M>@igb1s3La&<}D>5WW=F +zHmYgCxrfK~*qP+Z^w=304*?md>^IPVp_@zlc-A0s1N4t3$U}(1wl_{5BwmEPF&%PI +zD{IWRlfN5Q;yYv?`TYibr)^}H%9r-z0P9xh|1s3>zoL7rjXs^7Y+JG>h(u1y%1 +zc-G;28F=_2WE%5+nHIhOT7s`Gts`d~;F!`6_2}SB-zF7XF7%pL;|c^opMIo?0$<0Ws{ +z3jRj9b>HhEZyLsTAYIGpKODYbj4zk80X(1y{FwNl%SD)~zehDM4OQo)3=udxS$t92~v{I6RD8rhwga +z19q*5%aJsYeGqo<>+ew3BkY=A#XIE@|2T~GJNTRt5qXkNLFf4cWVrqRBjkR{HRwiP +zjQ3;k!xYdB?sdXp!+m1m-eK5JpaJIoA9>t+8|cFZtjB?Kk4rxz+vgs0eHncu9?xf+ +z^x>%H}yR?(b&{~bYmOvlXT|W +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 +z9&r~Yum71YLufgu>-)Dw`5?|w^_the +zauQw-y?dcUmS=yc*LYrHn*I?9EdZRIuD(D0_PJU +zJ3#-9ksVfdBRgDdk!PTvpAxTcvGDpgExaE3IeE1_NA*WTHn~^l&*oXEJHVeS4c@-x +zcxT>joTHMw{h2u4{tLW&nQ<-!vbK~Dp4atr)`B+A;{s=?tKnZRuaVcN-|>1pb$Ha1 +z>!im&iFcF^{~y8sSN6dFZ}<%S|2S*}(5q;dP`roVPsK(t63<(06m5o$Vg+mzl +z6wkj8I@SvCe98A)V58UqzF!TxZqU7l=&2v6@ +zT97o5c6#`ishfp%!+s7r7VlFyCEEec$SQu+$#(Et-FBenLfgU2o@@u-hV1};jQXKb +z+kvc!OWyxb@9G*Wn?Wa@kDL{}MtH>VeZ*KKUKG_~r49jkx<{KsMx4!IDD7`u+kckT +z>oP%){I>^vo3f+AN6n#`I=}W-7d+po+niLNR-V_b%?a@6%I2hfpxeb2zh>MCb@uJ? +zHvd!Q{}!Fyo$MM|G(Kw{vWXNf9UMUCuQ>ghjp93$-f^q`1kit +zfq#Es@b7Em`1eaa@b8CX`S*ZR(bbprf`5O*;NR0fBmW-Q*0Zjz`1j#1`1fmF@bBkN +zfqx^u>y-HSqJMyY!$-lhXHr)mej=)?Tlx1FPU!k|PyGAP=g7a2t}32a^Y?!}-#*?0 +z-){K~e0!p*Bi`$|t=2OT|pNO;t>`1&N2XQ|Kiif6Mv$s^#|bHKB&>VjwQK1H5Q +znPi9EgIullb+Bb7!PgN!s@o={?`5Uklw+jtaeINOQ +zsH3z-4Fg~P}{5ED1}^;3`;P&-q~ +z4Bw2?`M=hU&fjXW@1Ls9zr&*QKhllPzrGhbf63=3GZck8>^FIKyOnL4cHE`m-R@=e +z(CI_a=?iwdUjxol&t&W&eetZ-{v1AxMWHTB`C`qmu)Prefg9lqSaJ~Yi%$6R1>zSC +z`(>6U~V*Ko-;Kdd{`(cZpy%l<2OibOd#Jmi|y?2}^ +zMnr~#?hmu;v2Vyn85(H!UGDHXoDRFsq<7R?XFGgWnoAqry|ep_c3vtxEr`35Hg30L +z4rA!7_TJDyM@(FuqPLvWDeJy>**%1z=aK{u`J|d7b=wcS(`{K#{yx;t8lT`Rcq{5# +zVae3Ki`t7=`(&J_t9K`OQj3uD9)9Uk5jRg)`2}>^|U^3wY)Nj-ejdZqx!p +z4JyxW)B;1jPJw!z2g9z(;6;qx1pc~~hIhOAfSwh3o`MX5-1v-zwD}x$IETx%im!bX +zW2b<8&p0s|RvBJFydU*JP9Mhig4m}!m7J>`HmB30*Hh8-$txA&Ootl#Exe$$IYGVzH9m5>3Ej@ +zf)@BYq`zR4<{yk}S{r=U7P|$<#kiHFA;e17caB?GZ;3VRhgieEGd2!>gJrN^uy$*W +zZMTc|igFL?{S}1Wj9szHBk~y|Zj#UO-I`mBxXFvbr_YVXQ`P;h!%Ke}Wfl6=0{AH0 +z;<>q=;s<(+4OH=muqUY)Kt%^+{Go~;fc;#-&5S?9`3dEV=&_Gy;^GhAJ<+p0=~t>R +zqfWNrE6D0Y-^Gd8_{68%{EQQO5$CI3z+VC1w%Y%4AHE8kJI+ILFKU#Du%FaCWxZQ# +ztfRjp_Wpu4KViWdUQ%uud%}N)bG3{o?6d~wxBI7p9*`EaA(pTeaZjKxZmqS=&vOjS +zQ!oxb^$!s@$gyyYDHw~Q7rS0<^X`D{h;wm{!5j>_CFd|1a{!$h`ir(4Igf2^dW;%; +z{A`=K2{Oyj_FlA&vw_xkciqw^V+GB&apqFdLD}{-x=&&#&k_9?v2Tc#OF^t0bC)I~ +z?;+(n{eJ8xEW49e}(4INrWeyR!1I?LL>|X5 +z_IoJozNsMWUg-(DZ+3>=Ji`!LhWr;EoP)u4#s-+V92@PP#%^*s{tC}+xWyim&v6do +zjI8Gy5{>f>$>3|P^sypOK@HA8^Q;5TQI4p=d2*hE>nFrO*38=g*b#3~Q`?oiNzB=b +zc~IuJzZWE#8Y~lq~fC +zXs8(jP>r0&xYvkUXQVeOu6mtCo?0I-Pu*+JOSkGMttI2h!!iJ~QTS>=Ob@=5Tz7@G|6pzgAf=9xB-xEI>V~Ix_+eJK@ +z^lcBe`9>JFZ3XjvSbO@mWjq>k_H^PWnTX}X`Vz)H_EBof;~L6#8IN`V{ExV4yWK(D +zd=>P!3G^3mc9Y*TpLc)6gQem;=Rx>^8nItYyoF7MaplBaEvLgzxGsepwk#aY9eq;) +z>VDg1<``a!IB;YCOWF>e&UkaJv^_`8Z$Z1v +zL(1Ib(=QQu`;JHQ>pzJs;61{GvXFwyuFKoK%nu{^9%A|G_eP3ZkzedE=&Hu=B&u>OH{T)SRxGjp2DaTg*-7HE~y+rzN;F@9Zp +z0zB#KnxDDLX{)YB{JQo~TMqVy$y*w}2;Q>3&7X|3tn`yVwgdgbPab|1{W4y?vQ5re +zj_GERSGC$BZumaNwGsE7A-A>P1C!fi-g4$-+eLXtwF%xs*nDv-;?gc^^Ve^V6scTm +zlE>7-2YoE!4=1)2@j1q$(cdla%>b|YOT=G4OpARd71v?k3TGkG4Sf9HmKS{`)H`1E +z1?ZUnDqb}EKb#kp|GV*`(5dkv(3slG6)y^%=0#odqP73|ya+XnPV=JEyy&EQQFS+Z +z(Uz0wMa%vT^`hDy^rFVkpcmc!Pt=QWe(03-qK)x-QSh_rL@ydT(b;y-Dd|KPLMQU| +zLMOVT2b~BhjG{VGaQtW1hi*6Yq3@kUAG+vYpbuUCIqF02_Mi_fI0b!Z`sb_<{W(q_ +z`lCf3!ntGG=1hI)tse9t#4^X|L%%fiq1ImNL)C^pRDKHj5OR*1`q1sY)Q9@_QXe|h +zOMQqr665uuN4wC6?&(1vT5$^c&{T^)l--R!gfrIN>O;x@LVf68#e@D8`p~KJpp)rC +z|L#1f{NITOS#+V^@F1xRkq3Q7J?Oul2X&zb{ipGuuJoYOJSb|DJI#Z1|IojR2mLGj +zL#N7vPUau_cjrN^i~hs)phc(kpm@K~X+5ZCztCwtNc74tbXpHOr&El=X+6ju6Ql5X +z*y76nop{h^(Syi?PU}H2u?Z#*I;{s;V*u(^Y{F?Cbeabto=L{Zo%RR)V{vky2M=n! +z{y$s~y8g5tbXpJ6p7vx#yO#>J)9GgXM}K8i06dX8RvxBaBhL;V%52ay*L-Ebn(477pu+*?KRHD +zwj#dXJQv&8Lptmk5nOo}@v)X}?mxSY6iLhVNGum_MkjOV#|?x7#zZtunU +zh6k7{^eA$My%HA>huj{FO+#+Y;YsHpHyzIF#ODl6y3d|x&1Jyn=Q_lwB%H4}<@2>a +zH)7)66f!1mjB!4R=Y+bgC4#fi2XWTBKBMcHIP;9qPMnj*86loe>FS&ia8I5G0xr6i +z*P{k!DD1kaKtH#l&H*uIuEiO4agMb(C*#DqS@S$_rZDrCndf40Zf=27KljSM@!iEU +zlii(p;hO9^BQ6&hYA^M4rY8P8jp|SK<$8bi{IEU0@AE-Ia_Si1l(r~_t +zXFz!lsRi&oZkz+fesXJCyPtI;_u*{gi}>sODbDIx&momq&LQDkPZG`3k8h$ +zxcqiM&(yFk#0;FBIWhz1W~SoYOjqZHvh?^k^Ld={WPZ;2hq^fblh`iL|Cr;rEv|mW +z3?t_Hb;P@&mP7rkks{`_WZgfWJ!(PD$4+OD9!DJ7mo)htYisfBP3B0Ry}{X3%vYYP +zy%Fb!P)E4a`Jp9k(RqGX&;(#e>%V +z|KmZ3mpjda{=0b)^`E8CcOcuzya~&~opqm^Av=BwnJ~06dOnExn0k{p;YmElyb1U6 +zJUnzP$e-@>kvHKcd`LTzj65yOFCcRZ;Q0lRd(50p&copI`orGXS_9iHdczK!^S9<4PWrw)M;X6U@37U4NE5BZgm +zPl8o5;~GYu!zalr#51t5NH&d7_?Q&s^v74nK7O_A|DhEpHlf +z6n5$dISM<~@%vJT%*|uY2l|(+MT@cB4qbzJPh}myeyAA*{eaIApANE)---5|X6%KS +zI)2a_nJb6m*!B?Si#!P2=P`8)RUNCsc +zBVWquC0{zL3%>OCF8I=0r@)tRuFB-4r^=U>S@=?EH+%_eC2PNaR=zaw)cMkiP-i{q +zrh;g0xmBp0+y?nt>Pn@^-3mMXVdO)i%-UcR&ij$$u0QJAZ?lPE)||2Tf_7xIrV8%Q +z8pv%)UO`=~N7)vAja2>smCNq`Ks!vGto9^)usW6xo(Fx*S_e<%YF&#wt)`#Kp!3XQ +zC-d1sZ=j9vHu$LaK<8l2sUiK5QwBaNmCJ6O#Ya_Z@ln+pJ}RYa$Xs?i?NZmMg|1P{ +zTz1ek+6`S}`)r5QHK=DaLf>HSxJK9qb7`lC{Os9yVNz5d}rnDw?Ph8 +zx$NS7RL2b;)#dO}Jph=hTy_saCcT_KszdNmq4rx>IUAY`ov%N1z8B(i*_GJyhznC3 +zIxZwv4HQ!yVp#GKZ7vcS=Zd}+gup(LdiDY +z8Y54gf|snDinWq?>SlM5mjQM6lz*tlKCaXA)X8?4rw;lIeK%`V9=8v`qnY!~u$Qg1 +z>W(-UOr4Q3{|3tZZ^ZeF7(cD*p(BU8g0J=wa3z>CR6lbJLAi^D=VNT^xz# +zrn9#9b-mV`f)Q)n>OL+#p8fx<`r0nkl>^SP2CU3W2b`kcC45VqpJ}tMr)dwh>w4P# +z?f#9_S*SlDFWrlS;d>dVEug;N7@wC8bluFu@Hp}?w8Z75dtLVpneezuZ=2_Q#vmtM +zE^4{gSEKFtoOAzUVXDbwiuC)@XBwk&|vQbJER) +z@9UwsoOG;%4&Q5dqMn0+{xh=%I&;z;=q4u}bhG%JbkwbS#lv8uh~Z%#-Pa5rHr&F) +zV)CBf3q3cZbzqc-6@3mo?2eQ0up2%D4>Qi(_Q=D$$kF*(c^LFh+RM7+VKchmVK{Hw +zBM*a~%l)JF!RN}urhWz<7SMUvH^Jww7$owNz{9}LE=scSu>UIl1zkt-uOD0Z*ZTht +z{Og;F&g(VAn0qw*S@~DrZul2$pY->{@GtP{Uh}Vf3;#OyIq)xQd)@LcJy&cD|9aZs +zUqgGzzqT0stL_x|7wlyw|AMY_QvT)bCI1@SOa67V3;u;Ti%z!0KlZ@Ckbk__{0sTV +zP5xEg4gW&D_ip)D_Gjl`MIprK!9TSWae9RXyWKZ>P#XliYbndwas} +zRnD-RaeBYPC;YbELq8SwFa1XcukPy+m-X?mo<_6Q|D1b~}r +zT3|6X`rZS0??FwoH=jrop)GxUEgzK5Ze#jLM&LvE-VgYOT*9-n +zEk#^#BvtJEC{6S^cDC4g{{YeF`~l*T^Ywh;eAa~j-b8b(>(OU3#@hTC`poLnE&PxD +zHdPS*T!&LygO)yW4Gx1ha~;+L_WQA}?_QHM{@Bm^B)8bG1Nk*|7VV3-{e0U30WMu@I=hIkNf3Y2_A7EA-Z3Z +z9YO93-{-Y21}4fipqC_`i2H`_@g#rnl +zmYD}o@6|cJW9DR0H@nSy#YZV32%U}3)*ZZzRfl$uEcOwV4TXl06}N!yAdg+TEJH;mpaf`>e4y?KoF7 +zCVL!v@Vn-TA#(24c|VAGt2uX~6{r*WtYyxm!C%1~sCUXayx->K_t0jCXD8=SjXAuc +zUz2k{47R)&tEyWWtiJ${hFLxqFrBu +zXA(TT7y88JxkqETMU|VLN +ziZ1m5o+jYKx>{!4w;$bNUnBH54C{Il9;Ex4x6MyJN?g>gh?w8Grq=d7pnKZG8tfXD +zy1K;08$10y| +z?dG|K(f(9B=2$XToAZ)w3_9L*U;h(*PPOqIbay$QanXB+tT4v8L;hC0Ucw!=k51R% +zD^BYBReQ4dj{U+*2Z)9p1H@l1#TsdCa?KRYlkb0_BRal6hwQhbeL043bPT*U5+C&* +z_pt^$P$uldjl(uLrou+dJpHMlO>1!N3~`G+?Niv{azpmBK??@pdLPiK(W^b;yRKnk +z4A$*T+&hB#ZawqJs7F(ejACr|Pi*1QS(C!{M%#<_DYgURYl+$R8utKk)}sSNjeDT@ +zF6@i)ZwLPl5a0c&ew{VU8f?v@K13W%`GZ<{%Cnk1>8#0O&-Qc0I_$fYejZ2D?jeHx +z#rM+$nQaejy*1;8VJyv~?qDD31H~QeBYl9l;}P`1-)DyHZpb0eZvj6+fA5a~T+!#F +zspz*>%TL0b8*E2LB?0CQm{UFGM7qa0XxtOwPWbTS?ysV-W@junYgcfu6+-qW?(;*PVPz=n +zt|)7A>y87WVUc6b +zd&5JcfAT#?@b>U6qYpmd@U=V@b~V2lcKsN*`tDO<_wA`7_#J$I?@h#3J?h94?+VYM +zABqu&Cq3nQd(u<(`T`;4m!xfuIZ2r< +z`CQc_Zi1gi)+lZSKF@epj$_wNy{O?kSMwh_ON{84x7*bqfFD;R1e>8Z{1&k)?2EPN +z-kY@B)r|YZsWXx%i|-7!2j3pP+f@r3X_>d%-NzZS2b^L1np99utQ+B4_drKZm+QPV +zy3T6s@wJpmb6N9*wS~H?seAZ5F?skc|_az!)NkMU_o +zFela)YUP=pM^${9Zu3fkt`*)FjZf>bkIU_OY>(}-Ee-x+*1%yK+SgI*9{2j<6NP~| +zr!V%PDsNm@DgdSeoBdK~2KiK(JthzKSFxAz#dfON6p +zXj{J4)+TMR=3EEEz5*Jt6Eti)Xr`5>?8Ls1bfvLvZYsvY{m!xMA7aZp_z8USw6S13 +zSS%_Z|pT$C+Xs-{Kfb^xn@(oW3Gk5iJ#zIc`qe8|1{9Qk0*;cHB(bW +z25cEt8e7>XWLI?d)6FO5YHvklSJ_Tlw4I?(X*qICzd_ubF^>V5$4e8nx$NWRY%wR} +zk`yroeMq``Hgp@%)hweA34>R(e9l$d)>$6ap3!ppLmtw0Y5oCd@1-m;XJ<}|*o?g= +zVQOj5gz3(R-d;Xr{8x@YaLi +zvmTwd5ax_B8`O25a2*wma;3 +z?*S)&44U}fckIDt(7Sh&vc(UEB#jq$LVthymeHX{?Ve=#WNUZZ=k$FTI(nMJM?Tr- +z;jlZNSMIq$=aqYYg1_Khua1lI%8YJ!6eGU_);T8e)AfNv%b54jmTpyCD?D^Lr*SU<(? +zQ}o^BP1j&dTpPv}z>dN1O{lNhi1-fTAlGD?A>WW^&g?E`V6&Fv90Q)23!Zrp=UKyH +z7x2Rcyl?>*T)+cYkQUpa8L}?t*JGa# +z+2uJ=wlB|#PVewv!K>-oBXmnK6Dg(=&#-Ip=Tq#<3pR<^R*wh +z`>k*$4XJx5;;jWQ%J^kezI_377|)Gl91`jMi;#2QnbAJ?Z0sSzg>?L*!6MH&Nq92B +z??|J^krv;n`6d6@E#^!CZD+i^2TFtQ44(fbswx?j3MXp*~>US}FB1OkdrRNoe +zI_yh4PeE^c%DvS2lzW+Y3i=%C#fNvhZ>rzz9)vdQGX&)Jr(C%2!hIL+yKvuy`}#Qy +z&r`6a>$Rt8^In5`h27cFe}nsf#^;p$4*P7rDVK@SgRu6LS?CXHK1VF%*hp_YmkKv3 +z2l|zbgMO;Iw>2;MhPqbwvgRdBF98&H3 +zw!E4VVfzBy8+m_t5Hqo8Hj!`K%t%cS4qUMfg@6ND&DeQpF1V +z9)$Of9ZnUr_pOC3R>3fU`K>YF$@R!Xzl3W#uBm4zA7c&O8qNq2ZrY_0{|byN$U62M +z*EfYP5$}vJ+Tr_at?y$^XOE;81C1#qFTKI|sG5wGv@gzfje +zmx402`nf0C-3S|w>DVO5X?LcG6Mxh4@s11axX^|RZM)FUNWuy2x{AVKyAwVs+Fq6& +z47=%@$}rY%d04lv(08kRx$tAT<9)Y;=Xn@IQj#cU-`tamUaUPTMkp9Gw0~8sy&HZK +z=nh*#s27fBe}HF0@GGc3*%qY1g6@24^rOZ5*OXt4?XlnF5d4C+u>Asj|2yMCzjVfU +z+Nv+ahkN(|_;QBg-k&1797Etg5H9Q;`dmRP>t{n(eKkcSZHI1y-+zS<=@{gVj%i{} +zb48}~8xiN~S~PF74yTcIkjvROZE7vJ_9Mi#s`hq0p?TH(`HcF&|L4juaItQn<_!k7 +z4Xi1>(=p}66@wOj0Nv`D6vr7mE|hSjkCC*uFZ{I9p5cu88oPqWTI{Pn7f%-SNxr)Q +z`v!A;*ELz%+s?RVvLL)Lj@+UUbO0yhe%wzo)_jSFYYrP6)`33xP_poduZmplt&VGz +z9jtkt7)=SIA4o< +z&BGn;_v}x*1Y#jSed;MY=aq;(%Xtxp-nKvO4rPEZ^Vv67yD5(;+Gn%^S5 +z-~2t|B*Lg&FGg+Im@42?cW+606T{ZebaGACgdk_3);3~`-NY4zBWn)+-lf)jE#BpO +zyoYyl1IAk79T&d4XbX^ZOXxOX+JcpxctsdI6L?V&!lypueidUpflnwXJRI-+Q|u$; +zc>0JD#ke23PIwj;fM)8jaV0Re-lNMo3jp`4@gaXPW_&Q) +zPlUYp_G4lDLd=DIaSX=Z8=0JKOXD7+ud^omSyvEa=Y6&B@QzDcfH?#AiSwkL3F3S9 +z!g|0E&o1*oZ+C{}Tz`#we76toQ!e40`I~dN7QCu2@TCvm$8TOo8!qk#v>|!KTFis} +zl5cSB`7C(_p3PNzrPd}!*PkgoPVx_oNsR;Tm}4Q&lDH0;f$t^b(+Jv3dWQE$k(Uv_ +z)(HBL#Vo=k0l3NU+op=LdL)_c(X{<%jnvOPr7OTH(FT!F_Tyo?Qb! +zFYhZj^Sgxg^S05UCxnl`2@n3Yen`&}9@fXh>uSEHOmnaBDfkh#q;Y)icGxuz{-56N +zZMa6b@xGEVKucULkj02s{Q&<4>dpK5jHWyV{EMMWY8}X{72G+``!G)*WFa{&wDT?S +zC*MWSy0y#nz0P$r;3;89`xu{%zs_}Nz#6DI)qSFQi3413D;`+;SG0n%i7_;jpCwvrKf5Yyw)(M<8@D<~7acyZH{ +zzM}L){B=nh>d|S<8C;!H_~!&I>h8leP5>^EFYy`r8P`m;kKlJ<{41=kD(BZR#&6%` +ztFvcMnI$R<%Zkcx6k=hZaIteEe_l`wz{IQ +zthl_C&*|4I1Ht)YE2|2t~sA@<6_u2*`gEC+bh&Z}G&5 +zLO7js=NFa)1I5m&a%V-L64MAcs}=^FXtik3b!X{s@wxO$m-{TI{Fh!iA-&jn@wlbw +z%a-;Y>VX+kk;{^30jj +zXHJkm5~DJl@{il;swyd-m|iW%;Br+htjN5wWI-7a +zG@nRSnUBqoFVU$IsD33-eVmErV$7Ja6;;8pRoJij_%fzw@nWI{_Jy?_?$+3MU9P3L +zFl-`Qn~mmNu3^SQyf#j4qxkmo(JIDdc7ykf*Cw*5vg%-PaaDzEPxjAUorR9#?ts#Du9$YQD$({Tm#fFQye`*h +zyp>-Xs47(Rm#YqXSG?3Y(z)nrV4`1NR_ltnT-Q|QmM;lZOrJk%Nx7>q2uvysl%aop +zESC9UD8QPMDj;@6eo=X8X?dCDf=TW55n?`Q;Yuzt#wpjY=lAsn)$}l*&f~I<361rp +zz5HOwyrSa3VoST=NTnr3`N8tSV%JFWh(LaZvougzUa>5{yrLL$s|W-Omj;U2oy0>R +zB=N83{v@3lvoMM;W%<=*i^|HEl;x8MRD#t=wzFtz;nLaq4K4|wBwsmc`)nkCabZPe +zpu(Jt#LF()w>0c>%>$;HGchT_N&6$bTZZNc%L6#nSDXpxRJL@Jl7v~X!Yc6il7G%D%M +zCHlPOgZWkEi+LS=>A&ZdS7HB~V8r_hua!)w-;>W*ROK%$FJF|;MU~_`0L~h{f`(00 +zJ^8qomCh>GJ&_SY*dxAd~u-6IUmx@1gFAtrwhweSzZSD +zpqR*C7+g}g46?1Os=NwYsI;_jF~p85uXJ8Aj`T*SsyYR7xihciebB_x60nMSlwn96 +zIK8ZKL{anCmz8{DUXk~Ql?4_QR+ZcsP`5?lyvp(*WUBld3xm}Gwh{YGDbTwV11qa8 +z%?}337E~?7s7M2+1j^V*_F~Mjcv^Moyg-F>UiJL>_)~skpkjWodJs^ps0k5ng}5W9t_N{%D=w4vZ`c$33d@#@#v!J +z3a;O%%25`^a?*8NTv1Y1HD7IeF>GPsjR76LatwY@sqzZSuetI;r#@gvd+DyZ<1#P5 +zZnXO<*YcZ!HwA<4t5y_eRA(&Bn6vTt3#9>W8QKkOG=6XVk|@4j4h}t;VG#LUL+j37bQHg5(AvDnm=7+P6%6kwDGyJ^?Sb}3&?FAGecANO2_6aC_U71m85@vG&0neNQ`veAMX2PA>w>>FXZD4Z7zOqEjY%)+t-0cT02v#h+zS*Y$=#>g#% +zaZ$0jM9Pvb+?GS@i32%8+^Em~Zik0E0tW8ZjlXG3Z=fU9G9FZi~ETUYxB0}fD| +zB6tkpssu`GoP>AM{Rs;VWPreu@(O^bb7wB{P232S8C{X!L6X7zq!@Y9_Q{5$Wp@8{kUg@PuK=4Ja3@2^J +z)Dxk?Lo%pXcIhS5nr2p3PT(9}uHNfsRBNSOtzrtSHyDK}jj^3!Uk@z1rfh!stO*lJ +zDktAiT^MwIqcE7^oLsuNY8mcv*wGhGI_}~?S!Ey}n^f2Fx^I70dFebLV_Be6ANu@) +z5TEkL1S%kSN!dK}%4+Cz`6aQckEtj54Gh(n*JOCWo0#z{JTlwT5y||i@JF|grWcQ` +zDy&>I7Jsp>&`O9`=!is2ip3{+4n))mlR%(C$yv}}V7$`H% +zwDN1DlGh7-EG*_wq5D(?ieR3;MD9zI_Dj=aB?U%W5>h9RKc +z1&bx;!`5|D0wZITN)^n_#Tic6clrP2)ozS`IlfByjOvwa!{~>zQ*uPqjX|agLpsgf +zx&g@vivX>A@EIr@xo)(Dp}Z%;oUj1~pmbM3bHvW6C@+;B +zp9R?1x*CqoO3I3Y)x`nPtLL3AEObegGq4o4qDo2djQ8_P=I85IjR_FJ444L%F2;t& +zRv9&M6p#+f0H|9p@)a=NKn0X*=_-LCiasO$GoPyrz|cnTn-l*9%7gMQ_6^L4PMQ&k +zrn;*^y7DIL@Go9gRtW2;v#<=pA~byf0x~ktvSLXIFcV*vIf<@i<(cJ+EAeJPz6Y0s +z`Mlndl0lq>*s?_dkVx)LBL0%Vs2hRrK|*jDk#aE*zYwpZlbC0hl>9&T-UUAD>dgN? +znQ*lUBoGuW)B!}o47O2ehY$jxganfyptX()-WouJUbI^1u2kJ6 +zC|+yZErS=-E?~XvZ`bX%(%o9M3&cxX?&5reE7OGn;h3>^(L(vRbgT7lVyI5AUeBrDkqjD|o6anOB0e)@q8d +z8^;&76l(m2;d%gQsB3nJ^XK9EAmXiFgb05gqJ2wvc3ta|I@XXg?d${=HE1K!mzplZ +zP$z!!`}2)J`?$I@6WN56zb0_pO%MSi)}hQm^OYiT3p^ou(`FeWtFeVu$M0~28;M%> +zRK~#=^JMKJl!Ts5=KVQ?(nqUXZUS%HfhPt{%k}`H< +z*oSzwHHsv*(qOd;RSRnxmxULi75udXe8^y?J(`lTI2fd)4^8&#tdl*XFntUa?iD-+v!>Tn_kyK;0-47DQE*o!q?>SR?E*{ +z2s@U*of1@vE{L_ndy5w`id87?$#H7Y7@iTYX$&u!uSIp_OrVl$j05XJv?h*Q3$He6 +z_W=2c*q`4JP9)s^ZJkD8kz$4jp{R_ASZGciVr-t1ZE}l6Z~Hj&sc33!ZEk94VVAtl +zN?bp{KeZ7nZXRl64*fa%q6KS)kS-nCV4-87z#6AZBEI$ki>GOI&BZ?V)U)iMm5m*Y +z6E56<^&*%UsBS6Y`}E#>fY?9=*j3$3AVm>jW(33d3&{fDcW$F>8aO?l1}NH~#UzTxwj(DJy%d9zq?A9bXYR3^9&ny1C)@Sq# +z9-8NJAbJ8I`47Fj4{njhf95wO)ZSFiMwF)VfDJ(xNNtM0Z0yHRkRY5> +zx5UQ`d_QM?UBW(}&;zXNObh^1M(Ya2UYF6I!hm3yXcGrC-#JdR*h%@;kHEH8Z!P;P +zn50kuU7YkO>y!;%-0yOthKWw44YwQMbB6@a~30_ +zExrBm8lh)alZ4*{y^o3@)yVGYG7CH#bUT<*WI`g9m8zZ0Pk&l61AagnNGp$BOUz3D{4ccZwP!a~nIz?}+ETvUb +zgA=7Kbv4akV9d1g8DB`#BHgnkanK*DEtnCz>84j^ag4cFh-SLr_UhOBA=oxsV~_lPZ(Hv>4hu$khX8p;}7~p?hnQPL|*P +z-0|kJuhHN;$pLyyk8y09zi=F91D`gxxemG6qknf#^9bafUEIzz4$p6@ZEXPUn4|c8 +z7Djg`Vebeo!n9$w1+?oaoh32i5Zw}9fUvb(Y?rkN@74^dj+r09#2p}{;{eA}>@A`? +z>fYrWA`0f&1vr{7mgpsm=Fb^j!VW)6Tb8a(*&}-6jOo!Wt#fe5M%%gQ2Ua4j;SCJ? +zz%U+%SeaXcl5#xjqa?M9G|0KBv3tVV +zP3_aHG&`RNnS1bdW=`~(u-Z+N^Zhx&5nLB6S}zPjAAawyw~T5e@FT}(bV=*d*3l() +z9xX)5f(2sZ%vO(QWS{T5S_#m?fP#t@iqXu3x$0cng>^O7GZpYM${ghcU#oP#9t6HG +z)iuv%#}fz4*&A#t6=OlMd4SU+iv-UC3m*)+QOAYP_%v5t#KQW}ZsM52t{|uXWg#r%p9!tt-N$nWn$u#_=M>*5|bv5pI$zF;)J-x)s;>2F~MqF&Kl#>jWt5h +zvReA=-eXzd%eA5bF~7r=jx}VF%6P=yu=1v^kV;V53|vEo)YBQeVuP@Wnw1Hx|2vWfa=7YCOeRme%<^drj?hAsJRGZkk){kmUF> +z-9yhnqZ>|kfK`j~VuB9`(t*~{_ +zX(icPzL}|AAAkC$LcHM~L}ND3vo@-Pwm+dOkWH&rU&3@tPzP +zp~`4U*v-_}S1on(+{!)re8|-Q>z|GZ<}-iZY<9aoh(0=r@Yg>fe?Dv*G+RkVZvg3Wboy`-=C6M`S@fB^NET*gos#Ud`+zm6Fp<<& +zS}QsaB7+0g-1()}ko1*@f9urqOP!{YTeN6ibB%J`5M=4wXE?3o_J5WnB(n&{&bu<< +zS~O?-t*Ffg>xs1by9L&Wc9Ch{L4ruujX^9U89sLF(`sC1;eJ +z?J(RxpuKh(0Tw@eP0+!@lkt}bVm7oW-^hBk?kVlB`SGJ}ceCvRCBj3UmRcNH7syk` +z^>qzaM^94V)MBk>p<+O?n1%3S!1ay6NZnHH;Yr~+yom(i$+JIewXlo77tbaAfd(4P +zGP9ymEm#yb(t}s0o0c}{buod)$V6?~=VhBAJUt#K`Xqqt0CoWo$to64u$9rvUI7$u +zSyV%UfITQ>gSG^SIMGCSqg&|Q1?)6{^_Zjv9J2&w4%VmO^M|+R&9G6@=gA0$k;LAj +zv_U`8Y{_HdO>MClB~EMLQMbCUR|~=WKM#$aWTOc#0BG +zBcvy>_bbxK0b}-rs1?Ds0a$s_NA90T{gAp^3!C$ruv}-?$*R(&7NNtU$X}8UpL5j8 +zrqkK&r+~A3I`RO9`L8k(K)u6fQa5~$j1r-iwGY9 +ze#&4t0#1Ch{{v?2ycDf_Wvpeuw($cp!;u4QLX)3``$>qv9_oa#6kKYCaq(%2WnbHM +z2jBa*#6eSKc9TKKrkvcEbIvN3+v<k=au4gy42c>$T(Y6sD92HVuN2pjgG!c+WYb;kzm#^8yQbKwZr+Nw}u +zHUPeONRM2iWQR25Iu#^1<+V4pIERyQgMFebzo?f1*yeMIS4fE#cQCaiJh`c*6=X5% +zU|*UP5i3~I?s>*fs>O|z&eHOhKhmPeEyr6K*P@fdw`^=E&y$olrN}D=VHpI~I%n}h +zoeIF^=5e&_LImGpLOn|wZH9sno%K8}yY*`PKG5sF`cnr4fEQ^uK|x=qH{7_Qz5dM* +zr?!UYu<5R(BquP_oePjml)#eT4(=xsrJur|^5>J_n)>zEhadj6n-t+Pv6hYWTc=4J +zgZvbe240Nx+LZ~lBSMBYpj`r|_bB~!!^5K5unSXJe(1H|MYTb1#FzYtxJ6I{DOo`T +zT=KlO?z7r{^5bR%_?jEpt0Ll2BSCfM8Fr1NqbQDSk}i-gV1+<%+Z_QvxSp_G3p;^+ +z>?O&HRp|C+orZOOZIDGFN#&le^u2k~4jjKAMN7it(?ApTb1gt5+bGZx(+%ML1rCyG +zY^+FkB!Fv3O`h>-ut9f@B5tRN{q9CqwU)j@K+bvBL#}BSmZaCDZ37Hgzc~E}7ExU@ +z(X56hKD(eiv}hg(j_w&I@4NQ +zSTpBJVmpnkg5MutnvGw~x7!E6uh6-Tgjg%nZ49KNWRCxBm@Kmof@IP5Lc%@j$3y1S +zv2!|4CZyXh$jF7@PB1?=zAz4IT-?}>|E2jY+Lnp8V)zg!XkA7FrFxtfw&aPFo<8oZ +zGf06eDRF#~-j_&RDN#dnHv;Q$k>ZqOT%ZW-hNWdGM{_$%xBr36Zy|lbqJz|tdKr@n +z2Fh+C(uNIdHxl3myJ|DBa35!uJ*)t0QD(h@hBya{`Q~ONqHDnh0j2PSr8UaHKQDYr +z<%G&hrX^-fy=cM|(%hPw*t2LZ*6!LVY1GTKK3y}leInC=NSWK5Pjd6T&gb(v*~DV{!`=AuEI_o{bRBfvV*oNc|9gfBt&`BfC8jjZ(aqo}UA +zC5Y`dVHrp}yexDFX9eidU{rM|n3$3q`yyhg;+hYixLe?8z2@R9IUkMS)gt8ZqxAbuUs>Gy{X +z+kIX<@R8?*Ld~Yr(ReyDFZV!J|4zQJhlEw>M1gA(SyVbMyoiHXjZu_^ViL$#rJ?xo +zjUaF@(M8w+#j&W=&Uq10Aj984v1Uk*M2x(yQUv`yi?Hxgk?UCJd>{IhM!*7JF4x}kJT>^ +zWcsDPOB0DzS(;EgHZldR`H@wYN6w3j9D&p3Vv*eLBWVY>1%2%L$v8R=GgEOhn#sho +zIzRAY?7p1v!MXeS&K$5wA+8n+&YqR;wgWX)7JE-T%Y?AcxY&Y?r)!5U6O*%>ZCvVM +z?C8PlEiJ2M@fQ_|$x5)SOxrA|V`X+}!_>D~EO#m-$fcI1#iUK8Z8iWPWSNz!={$C& +zMq#(f0mqJRSSAn5{R=F5KQ9{B#9epxAWH}Xat@IUa(XbiT!f&veyqWks9iWmP3fYl +zj>9UVYklj&225bz%XBkfbX~?JxDxkRn{x7l_~lR<7@z_Yh}9~casxj)xnOPo(sTS% +z2N1K_y1?+bFdUfa@@B0?SX%?v%n1i&qKqELWJVmgZ0m##jat6U>fgqJte?Q)MbNL> +z4Kf&P3WC2Or=$Z+8yCO`(r=u%LT)J*4o15j6-W8KdqRzu%4&8p<&#*o7* +zE-%i?f3T(#z_=_CYYxq>(-Zg=X+HJi&DP;nLPM=1tC=w&J|jGJ%A`x#jwKR?XwyOp +z0#WIu$MrhcE_-28Q%J`dl2`oFL7_K{=$UgQ{$Q&SGA+o4`8G;RG +z!o_xjb6oRvcr-X&sT2N_Rca|X2-ZtKHb>n#**dRl4?(5RFa{52ou~3cF?AD(WRQ?B +zkIW+#TyjTJvf9~4-MOwwB)@&osjj1)>(X-|G<~W|=Ls8Hi$Cul3FEX@8qg^&W)sZw +z=x|_mDlgm4`k14fC$rqwkE59edPN!(s_ +zSiK)472Vr#LDsQg=5GT{X$~2$(c+ABp$!ED-P6wcawV-b^MXlAkx`fkm!z7%#%181C%34}z!nN6@{}hn4Pg(ZFlGPf6?o3BN9L=M3`RL;iRBlxpYZe!E3bg8%L$iWMVs?2B_Z_iKqk7d^z +zWcDrDze#$UPae8!IU`;^B@w@L^7yHfCSEpSdSV)>s=A|ka3_uBkQc}8;^DEAgMMe& +zeKWKvp%%7_bovm(NI_M9Q$q^LPaY3P7UCuCB_(HkMW^&WXCtMbH||*GF=pDA +zD{a?P@U!D}i!_z;=H?oO@a?}Id|T6uL$7T^&V^c@%`)IJ#sN=eT}L~K4%U)ZxdkHe +zI>;DlzEZ_DWWTBIg}Z8j%Wj63st+nHK8wpJ8mP-?|;n)A7;sd?PH-13l`7 +zX$~4Q%`1@zW-AwTY#D;-te~A=<~*}b(d#i+8H> +zDx#H$`fdHvlB^SdcupbB(|$@xFr<%nYx0yzp>P9aXJAzWV3A35hJT;hM!noe5V<-> +z>1n#>xE|Cy3Z9BY2r&6&P^M3sIC^Dej#iMJ; +zF%+vW>@S_vXqx>szAtt`PWug9pis`&NX{bC_r<62VI9UVnLN3C`lUJ>tq*jua=-ZV +zwhUUyw5CNDA|qT81*__G9gei;vSbWuol}Iz?P^g}&m9L1s4rBBT|LbmXPPWK(EpxgU;>!}g#Ov`fnygH +zk6onG;f_EP@HU9h;;GpaQNH>D?G_r~aG4VGg3LM}p3HLRNu6uAUO=XC3Daj!RHsc{ +z-&jh%Tx?iY5-uMrR$M8i6z4u3N5gT +zlJuAK5$P}cNBXSak~taXKP9#5S_hCiJ`d_LkhhU30M_l6ku~j) +zXj3(UQHdfo1xIRwJqn#P5B8jbBNEuwNJ)Dd$0k@SLhj2>>IS%9{(8iWLi%N-(}&tm +z)-1@@^ROi{g#St=JG~PKEylQ%=K?j +zZC+Co4tu8ZWy@)l^dy7+v~x;JEp_meaLKd*jgzZm{!40<(rPn#1#AE%M?|%k5Dd&Y +z4!05R=V|wVUx}LjlpX5aLPMT3NiZvsGlTtXzRxhKwG2PZVvQnFe+8lB0b6x*N%7+z3OtN0>H9=9?@EQ7}=%G6G>;wm$u+zcY9s+$eg+E+Oz3S +zV=LC}lQz@IwTMI}L+6@Bt~yD%=Ib=QZ9{C=;z_ng@ZA|8es`JM{(zM*o$`BJMz7OD +zNTWc!kOvmj!4P|rO=L5F)9te4mwRM}&M=WmQnPqoJsWp;+c^A`hPLj9YQbH#G`y(R +z|I)I^eSvqT+d~GNW~@Mo>X>rG_2lf?tm}R$iFhrmcurg@^vkTVs>S3bNu+=uUjs~O +zDz^pb{F-m`)WQ*hx~={%XRc+NM)1Xz0q(_#7rMe2Hn~b_wZ3hV)3Q0zv}eUT$pQkqA9s`qvM5xqGm=JZZ> +zB@dK)+^J$28m`cEu_Z6|*lYr2ji(`w$r`lR{5#CSEf?}DR1XwBhKNBH;??%CaXfZS +z7-PEogPHNtogdi<`pahXZ8))m))QBpxo(l>kD0k@n~~2XP^`)4KW=4mHz?#qce}uR +zuyX+@JT_ca*E*R_swgx=+>EfDt%1~2OsTy*30v*xqdYa;o&^|o$S}~8QZOt4>bWee5HtzUuuZkuyooSG=8C;Ibl^Lw5Ncv +zWi8%)(VedMW{b2?Nb+1;+RoWQ*7r+i2dSus%^tHdtebh%i@d|9ki0`p2GS1e{RjiB +z+_r*qy0uGpXS&G)3yz!sM?9T~(-@K~Jv#==SwinagdubZZAf9wdW4eNkire)JC-MA( +zG;Bdg&1u-hb{xczmSr*Ngc?=~*a`;4mt{_%Mb11!g+o;%cY(hu=Zxn_P}=X5T>kJn +zkSO%p1vZUBhHtv?_l2&G)kMVyq%v&?M4lgqe|$NOob?wyyq1>TRv|UEsQ&G2Eis?o +zs$1A=ut8ZfID;f$1?aQ}mp{JLiFUM_YE|rqoi)4Nq1_u5*5#hfjXu>Sl&kC$#VGl& +z>b+RsidYgMG(}jMh&#p(HEi<))pxC&vGqk6yqlx{p?1GKLWEljn?|Z2A9w&kJd8LL +znU27$P)b(cnotI7_I`FLvB2%L`ZsWef|#Mr$F(U@2!3BAb??tE=p&nF)hEkdKhB`b +z6j*St1F&pnF7ONS6uY1B>nN)th00d#Y-LZ1HdRwDu`RJjNo7L_$|$e{1opFi+?AF{ +z5J9c24;uJC+(5xN)=&}t$TF_0UB>Z%62H>AuJzOcq9fxtiO`EGw>sLcAm2Q;7mEEK +zEVLsGgA9%Ai~}9){C_L&{dg|3%|=B!&dYVb8dCOc;cf%z!ARY4tNY7rlMC6Z*ZpzfQ^}m`-b(nljmm4USWL>SYj<)TrfZLhVQpNAdn4}9 +zdW$T$kYnj_E2@HdUzuhP*CLHC5pYJ&cyc#F*`!A~8_FcJ23ufIr19aea#=kA%CgGI +zAK8C;H9-m&jc3=6e9y(W+|;SD;u8Zv@-6#SBgl_#`vG>lED#dRly#z=1iLfW+y2lI +z_X7hvO}9o4%xKfIwx0JhfKIE(>a7u*fW6cDqGvlrj5EzJ{QMuzFY~(xz9XI!xfc1| +za(`kA-rhV;c=!%YJxMSm(OKUWk#_{$r@6ul6I&*;Bd?CSwaAk92r&tKLidDn;N1TP +zsZV__ti|&PVdzi`u`NX==PR$Frm>E<8Y%Z*)gggHL +z$XRzZ0{gwXSb{~)&N#W*wRNg`r8=!_o&slyi^z7ThF#C~b>kOfc?7G(g-VWq*G~L{ +z;O#NLBidJDZUtPWab0^K#sDEsiG1jMEGm1QRa|C{-B*>7M;zE1RsI{k@Kt36Uo_v= +z!t%d5$#DrUHb?k +zT!^oS>CUT9~3yGl{k{o~nHu~g(2yazS!$!l|yYfS77-g7-TFBy7cp=r>& +z=T`DQ>GnqoO#7BXvtm{%n#a3{3;S*}o4B9Xx7@T1jODiVP3D&J-oOstJ=ivZcY~fk +z%yjThAlp$jJ;1kyz4i&^aR&`$4LG%Ms|PCj7mj!m8U|?Cu-l-OW(H{-lIM8 +zIJ0vEFzOxYXCG$<9f+Cy-CIM0>3diCFf-VMj@|hP@O4%IC-1sEmur1vx$Vqt)paqm +zd#{N-zIVj9{eFwz`B}fYZ~l*&bvw9@^FHz> +zaJ~C2hwDOceag>F!)kC1yhRVD3QWPz9Igk0>w&;h1ilB;W-u^yfbS0Qy#jof4&wJP +zU;?gpz<0s1T)Td2Zo&2<)4|+?pAPUnHDpd%3tlu2!T$#Dlid9SQ#k;f8s0I!DaVWz +zo`d@@M1f!PqwNbL{kiFTp+7HuFZB|7X0T7Y4ruodv@0D1?Rd|p?&)I?SA#7d#By(g +zeuAs?Q~U+yZ1^Vdj@{|J4;&mt_0Gt*d2jQJ+ltIf{0*OBDh1D$!c?dLx~1o^(9Pk* +zWnR^ZS9(>&pCcMH;3=-J +z)31-2!GGf|5FUbYf-$_2UPS@C^xpGD=6Ap{>ztfQ(RvGOCf(*5uOfZ_^S}!2x0Ghx +z|BAc+x}N`rsXX!LT~%6lyYinly9Sn)(ifaAouT~(z+ +z#+lO}ik;d~{wp*1OI=Mj!eblx@NZgrUiTR{uP3{zUixWQLbSM%vD0%p!HsL@_5Ch4 +zub#MG*=gzFt?i1h;aTCP6ug`UETV_EqN}O}Sek(4o!GC;JBz!Tyd_>dn4{*l3wflu +zy|ygVb{}o`&8O`}Uc8h(SI~F2e)BVJZNHtJP2P!KybT$XygO&szV~BhSLra54}az% +zU-FSFJ03)?=sn4-+tsYSU7a`NzTGF5yOXiar*dN1GG*_#a;jHn$&|e-_?;zF_Acgk +zmQ2}Oms2fyG8K8!u?=}LIVbi`5$h`NDP#b$a>$0H`Kn1 +zc$%&S<9MI&;^?bLKDcfN*IRk_dIz}P3$7U_x1(@FZacVcM<+c1u7ziP-wv+xk-h!E +zbpf(XI?wCx#UEr{nz^QOB{1K9v6E?Oe6%}!cwa!KUFcO^ESdJ7UGeuMJAQ8}*TN&K +zk%L9dzvcRvY3BZ{lAOwSz~Kd7>Z)2ly{pR3REg>^r5y5q-Y#-IA{ +zT?3cuys+iAn +z;pc^Ikg~zaMz(N55bqx8yjOf97DG{%8i~C@>EI=Ak=_ +z%=D8T{ichCw|fgjGmV=b^VY+5Ou-?zFIaZC;_v)1zOcf$G0=I!%NYwZW0d-1Tzug$ +zqj7{2Pi*5|>%){}wecBg*M@#!JBFmw@mF10{R(>u*ezqga^S|2Jq<1NAhjy|X +z#zJ5IO%wl!cQl^0gBVL|&ihSQ)quirrf^H_)T!ftWlnpkEB$;G&#s^kJ)gmsKbPh% +zJD2J6yV5j1D!wl4a`@^=!!I4OH1*;LC$` +z^kvtUR{*P@Cof{Of;p$nxVtp4kIGZraH+EuC@USkDN*dZt}+ +z%g685m6>PW<(Y@B;h76Mr`aOJV +zXx1Qf`VQVD-u47=-BD=vJ~#vzhnl@-4Yj^aKJ;oYJJr#O#eT{qy^x7Kq+8W^2 +zJca_d;5>_U9$uAGS%7XdgG}X%ta)_)*u4)Hnmx~%>b%3w7t1>xT!I7na=*aN5WNe* +zV+`8}y*UPcE)s4;pG|8_^-lC<`uBDGM(?D5U%_v!rJ#L{sSb~K{m2$oANTTi!yP%! +z?FU3k^^A$%83_5HD~gq_1oGZT76pjQNXMQW3&P?+_l +zPtWTHS!bX5g?IS}&Kq9w27B=jYa_g9E-SC|F1Ps5_r-h{F7$mq-+h^~GRI5Emx`jh +zj`?Ac`Gj=eKbgws;h`4`Q=wxRGs-h(ftTG#TRbCwXn)ww6Hc!;6kRO*1 +z?;yXhd6H?HN4|bX&d+k+g?FaQ4u^NN9y_*_n}^^Z*+JGO(lz{1c;S@O;GI&Rcf3Sb +zd<$}K^)p50cK+@@5USMNp1IiB4VG?Cgeo5d-as>Vj_o=LKEyD@uV`V_xv>!xe%@^C$?$xYf+mnv}2ni54$Wz!d&VfhmXfTN +zEwE^c8^gQkaC{(bqsZDNw2yuTIKZREz2MQ#sxPANC!$YF(f6erJDYA|{r?c2dWKJL +z>p|mcOvzyDM`~QgJMq_DRr}Eo?;wM3qp#C}EL!UqoZ(=33s}}@UZa5J)85hB|9hu}J>C9A?1V$~ +z55GQuFaEIj0Q*tv^cigBv^;v=Sibg7>x{3452WkgL)Q<6PG0BXs*4XEP7DUdLdjO} +zC7VmS!^SYApP|8Nz`OUw!wV$Odaj$TmmaE+O!cnC@1bw$|35tH_rKVyYHs#y|B~IJ +zhwXndwj(^(;`eWL|3u;=gp7N_zxBXD+kbkFk1|K(&#o)7=6H>%`~|!qJ__d2&2~iB +zBU6l*e>m;C%l6#cd8nx`yyR`|w9g4fJ!jzrM%g;TBmRiBE2O(S@Z%r2yURUyQ)gUo +z$)?)9!c<-`2M>9}zFZe7yKFSF&pB>jx@= +zafJtq{}&Hbr0KiNALk0M>h{LWIKkW$hnX(iGe^yDs^~kxTd+g^={FC2FfNFH$i_%b37mWuORqh +z%M+X~F+ykm*+mJKs&3(QGF-}WvC3DZpf=CVN# +z6`DL``D@R6RblMpJ;2Zg3~i_9mF*P_TZ)bMO)oC^6*1WnTN?a>O2ZUz09NB&0{t5*fXs6dF*2!Y!Ceh +z^T-FjysoLaZI6yL`KM;VvZcUyH`rJr`-&7!(?V6;zRSb{4_1UEE4@G +z-$AKaHc_y9=TKr|%QT7xHBX&8V@XqlcN#X%;UyX5c?1b@+Cu!2Ee%KRFurIFe%%s$ +zxTWwAhY?TNaF>bQ1nnP(4&UW-?pNpdj?Xox9Cwl( +z`()sV07u%VQk!!bcMNU3)n1&nbpmVagaP!`pU-y2=^MKxw4A?c8{EGyxL29Er{{up +zYI{2W(Z9wf_t)0N7D?$V`$A3ORX7z6 +zg_Ab^1~?I(h4b%@()uzpk{tCixklF_!TkGRvju*oo)4Z?`}MDQ6-Qi49eFJ|+{Aje +zOBUew(sv%?d279R&-?3t>s1I(uS2^4SKZ)Z9syiu2r2xtwOsY;RrmAgc=C@h_;rJO +zV9fDiHqL}6&09PuUJ}k2Vn#B;9JrPbA4&dngYSdzw&O?~t^d)H*LuZUp2M4X@Ccl} +z*-IaUZ+f;%jx({3irYNqmOmgFS}B|FBqv8~QWywm)A~T>FJZ0T#CrT^a3Q|Ghre16 +zqFta5_#0XNZ$k`iPp*x*IK|jGNAxk~_;8z)DV52_^4gWGFk&@bua!&3OVUnFVyye{nI +zX3Yl2>*DbSXm}4f6W}TG-M+CSHjz?p1RNJDXXJ?+FeKG%}RzIe{iHpwr1%neAADjtMqK3ueQ^N`0mfvS>&+< +zI_bYcXZ4DQ4Ow`2q&prSA5dlvFwdiK9fo_~;D+i=~Vuh)1sE!Y2F*K7a7;6^kw`xe58BTo;D|UzT{$!zwVz3H3HACYf{k-&*a1! +z&de(-08ffz7Ib|!wF|*z>FY*lG8H`*J@;d@~zoL%`W|a5f|hXFG}6 +z?Eto||3K{V#+=FxKh3FxM)-)^B1?B;yQET)t2U$}S0_`Eug^+Fu8E~0-w0#J#I}XP +z#3~0d&Y<1ial1Nmb61i7ks51a!L{}$3P^Dvr!;3kZacZ-cCV+!i?6u&4GZJeIbOwH +zc!r#i+FtRzog_&g(IMo&^K7kr)>>K@CTbSL{)^xN=Ra`ov`xi!MC`tr`~ +z?A<z_M%s{ +z37b9)KMD^YTVE9Xg?2N~^Y5?5ZnnTIX_}-r&QGpcWLD;pcLg2?ksGI2#V*cz41Rm7 +z&7)f)nY;ntXcjT%SSl(XW;HqVg=O&nImZ#tH{sjKXP7>I82Qg;RN`H)!sdBBdK@`u +zdP1PBi?lJHGr|^W_{2z&@ +z`~O0Is?Opk&cKi}_FvCSf7^qX;z#mQ_BmP({*6;D2fcJp=h3o{$m)Etj4hobT`*TJpZuEbc&7Romq|T!8Tj|;=}7fSaZ$3VN7Rmsfn#}Os*_M9_yes +zwLc^~>6-Af(O)40ZX|ZTWcRbttCG*!eVRMD);Da5`tZ4W*0b1g&qc2^&qbG}o{cWs +z@ND$!v1g;-FwaJ>-Mu|}h_?0qT1!@kVv4ck@!a0osnCWkUn^@vM{z%rEbLSHooN#g +z`2|JCBTM#-?$fX$Il*kIFE-0ZasTu_vHe}w=H4;0pe*kd_GK1^s`FyW(23}to5x}g +zZ1X~!2kQCd-pZU^Kp-lMAsGAG25;=$?U#5C-(i$k!CNpTAN|roIQ%ODA$GV +zkUr^K9y<5Tp=Q&Tq2}B(hnaEMb@s0p3+2C`wD*4fAMEA&_dj)7PD4So+$>CO50Tet +z?OW-}V^hh{LgxJ7Qw3(rvut9c$A)_a=2I`52DROLPO&cWz@?0`T0-b*Y@AsdNH +zCx@}WRc)s6Y-IoFRA}$)oa&X#eKUHkBV{Bz?)g8AMy}UN7E=t*n098EZ$- +zAAP0!`I(o{9Av|5j-UFhw_tY{V@FL)FmBiwidlGw9cROnNB<4L(ucohrkN(%-L){M +zzU|YT1Hm5I2yHgJniG3~z4yCLN0jYaTx{C8f7g;?v$_Hs{yK7! +z%2Sb&@w-F2b5f_K9{pO``g6UiKEMMHM&Q8+d>VldBk*D5s^qf~_%i}OikBnsWCWhX +zMtaWLtD1|qpsUxpYu+*nZgR$RxrQ5~b@f6T3-N#E^m&^9ggTFR`gYVa*BB?Js`mHbYD!S1RebyWO +zyobH`fPYDbZo;nZC;iDs`$K(~XKYN-R*E%o34c(&^XyQC$a +z<8QupL|HrZ*a0oJ(nhx7K4`KDnvfe>)DF$s%N<=dJn^+MGHT-*_d-7R@VR0`D!M2M +zf6hup>tjy$uKz+;1-~QQi*PR@e&Alj+kX_>__^h2+c=od0OZ9R*p7Byw`J~EGG-um +zBwxH|5A|+uzp^6Tr*QQw&w2mc71!SY_Mo5j-|egrj%GU-TO@hDsqDkN`8OlE&ct+WOa<4YrZR)?tbBq#*QIf%b}O;n +z2hm^0kC{XHw&;d(6U*oK-p809{IqG*HfyKJC)fVc?of_m07v+jfj@Zy@a=l5z@%!n +zMZKT6bI#sVUi`Pw&ghSPB}Q?|ZuaCETk<{v +zJQ3iD08a#1B9b??#`)4(mp2W}t$#mKZpKRIgptoXb7IA{d1agK&#B%+4!QJ#&P|ro +zGG1M=`QCM@sK&~dtYi-3Shx9)6q+{HWfEDbyrE)vu6@*PxhpxVUch)mV)&O_8-NZh +zLdW%=mJAJL?7m#@hc2CXeazf4W|Z~M263;Dwf4Zkw@=wz`1UFCWA8%_PajVXYtAo1 +zsq7aDiW +z1heD8;bt|uTj!&dx1{lUj?+QT&>sBJw$n!e%brtKX$)ctt2D;BL(QrmGlqT-Ooevg +z>+E}iGboI=uMFMJn41e3ca`#>Z`8rM*?IO*@;SCezeB91?WYAsvU1n23eBD9(p`nA +zkYwrA$yD^~vr^F=@QLD)%Tg{LxrKZ?#Uf?D{u`fIi>VCnGO^Ea9%ENcvDrPEv*Z5S +zKMnrh$-3X0weA%olx(BFNE>5bwShHH9POGIF-hb=9elBLw~M7M=lj=Zr6MQ8FG2i9 +z>;KMWrv59)kG9slGP~#a2Xyla6I+cey$szv8C&Tx*7#{lMwDGPuh?ut2AsdYz)WWS +zuR$-rfDG8g_j75t0bCYW?6x+y_gUgW*aEWgS76)AE?5p;CExT(^ELRc0yc~DESo{s +z8pDpK`5RgPh*vRg39+RGF8?N7=UMUPil&9LDF!sBJgCJHl#x^UlOSq+UUvORSLE0x +z@u))2yhc@`r|OD*_l%03e5iiS_&2Wb4QYMyZo0vBWRZ}+959flf7$*XDTJ!j^dWVV +zGIf@$f0&+iws+XQU)$~|wV13QnRyL>EgI#+VSUIR_ib{d?gs@9$-@jBOJ0qGBU+*I +zQ%CVXZLOcvFPTKo>bKYWe{yTXC)38Y%SNp_5ug<|2 +z*iD`$>lpoNb-ncb*Tbpkxb+3*j%aRuemEK0&zhDW`x8F*zLV2%m^{tBZxc7?OjZ6} +z=uFm_&Q|94VGRv5_4l5i+fa<%G8uWjDQAD=yWC&-8`?h~sPK`xvm1N)C%J2OMTd9NZXNM}=_tJl1 +zZsjQ**dLMH`kQxSN1UHqe_DYln#!8qi+}s|pA_1-sN#9D6AOstDYkwGzTk4?%y;o) +z-ex~w2r;};VtAZ=39lt5xrMmw(2yB*ZO<59X>Mf+^PGa+FFS1qy7s2>{gHfR$=)x7 +z8dh)HA6faE{gIbO?T-uwhBepik39GfL(IND)RZaTA03J%wt3r7lYbcdrIxYFhZ@za +zX`ftZW_}8vuAH+&*bVLTi_PiGqn-1f$(qkZ=_g9x(N(|MAKjeueq_{aQJoG(^UP&Nk{lm{KZQ)n9A=pvWxt|GI$EOb=c3i@LQ`nDA`z43liuUNs2 +zou;7#nDhUT47Hz2?lrhm{TtQ6DgMmyW;pX0{#oIebGPW#;g63qZR`=`ajtdvQ(j2) +zmaP8nt2y<@BdZ(c<(1XF!JPi+e5m2b>3ndhc8&8!lnrk}PA@Dr%V;AzZ8>s!muxk@ +zUrjs7>4kxuCZAD!xd*;nzoN4uEtlchbWU$|#s)vMk3E2g;a&J={WC{tzbVtc>;nAN +zp%XZ7bY#q`r+$zf9Owx7+urxOdetHF#rn~fe=}^mmacd{c;1wg({Kl|2k$#w89$79 +zTisGE8`SBaUgx+j19PwUAI#jp8Q6k0w(mzW_qtvG(UI4cr(mBM)5|?{q5J`RKT8+> +zmN{vz-V2B0x-Xwmys2yJ{{{aRe((-;#@o&(Keup#Iq|j5ssN5|c@fEsO_QxZ7JY!` +zAP#5+bK-K|9L4*fT$MO#ZfbP?sg7*$MyW&OvSxS2HwxtC +z9&hlm@{1I+yD^&6Fb;W;2OqD_*&o@1%-Zu1a%yi*CB;sP`mAM7EX!||EZWb$j%-`) +zFMO@|7fK +z#xXB*W6fTRsW@6U(a+L$A+n@5|L?=#53^?$@aD7d^>*3Xr)T&wxYvzu@5#hm +znEwoqdMZJ?H<1Olk8vN;$4@i&Wf!ZTHt?l5jD81t(|e=K)=dcdSG*=|pJw?4x+WPk +z#_vlw^Iq=ma}9|l?Vgu>-+{i*H6Y99>W|F&;`K3eYviN(T$9iZUzE=k9coU!AKxlE +z%-q@+UrT@Gb8-FFzjN1*=5y`&Z}fc!eFUFNJZ62a^_}F0cUk}F{j5BW;mYIStdQcS +z%Hvp;N=2_F_9DOO>ZJ3du8Fx^4*4rv`2@Kf!?SZaWH;r1j9iW%gl1k|i!2DcT#km5 +zJ~)?SfVnNypSE+Mf1p=%#!2yz73f>-AwC`Ca?H9ew2)kmrGHO6Vee2ghJ21C#Qle} +zKk$8GaU;p$7(stbWSa6ZeqFmQba=d}e%j})J@|R~i2}2VwYX2YADx^j9hHp!>Yu#C +z>pl{#PRCuWwd|Y@ +zt$F2M+y)I~r`w#4HNE6?5DOi|c%|50A1SBf`!1(rT#(c8nXH_SPiMs{;IXugmYvhV +zSbfonJ##v)+HhoEjp#52y~;Xc&%)2^;Q4f32eDAg*UIa7z|ZTr*X4EehiCh-1_J&U +z|EcW<<#iNre+TCTZ%3CZpW|iD4(_~PIUQ4Tl|NL(T4{M{q`CbId1ce5e9YXAZ@b)% +zhsf>FS;cgIhu^o($jJ@Y)Kkl*n(x=8Ie;fpBOKExy7dKz*C`np_yu+s2)R**S+T$ +zmn*jE64Ri4w6+7(WD%@6#pWJjKEi9V%*51g-+1bP;x|0N{SNNGaDHA{cKa8I5A7XI +zH2o8tZ$efm-&;A}OD*i~T*?6I=h!u;x_BF?`$FE7^u=xDtPP^h%Nk(p;PVKdL4PvU +zw^Mf~w$IF3OFxaHiFZfrp@+AoatvSyBM=0RcLksw|Hw8_jGM1aIXUH^l#u^ +z1>EW1z`csT*8;cN%U((W_grdA2xjjeyW;mKCuU|&rSLHaTS$3$!5p`a@+$79 +z{IJKJsdcf}RBr9#Re2t^l;-leyhx*+77JH7uJJ;;*SNScx +z2fv@^x9}ePeuCek8_!ytA25~d^N$sNp9Zdn$*)oUy;-;BR$9CSbDWr4DcWnE-Y32I +zbJWSWhfklvoSA)CUt`Yp5`EYaT}eDcee=EOo>AU{Rh%~#Jd%CEm|I76RourI=B+-J +zf^B(e1_xVneEi%3F5d5~DrRj3^(a=IO+59JS1 +zI(HT~{#>`--&r9zyc@dWs(JC!i$&%a{Eht#S_p>$PN+lD##~ibFg?$UjhiR6f&s#;z-&Mbd0cB*PctQ_9eG=M!b)pi>LKk#qbeY87ql$UO& +zdLAnaye99LUR-&d4-vZ&jIrw-pQK?U*GhX#-sG+d(M&bV9^%t{o|$=@YH~n>pzeow +z=7FfUK=jr824~aY2VRw)?;zG?Ym4M~RnspVXQoo$!qygfhk7pLN2UA!6SZZo@)D}O +z5!3|Zd(lI6^zYL+fN|?3hbuHzdJY#d2k~Hl-$Ld9%{}Ufc+?V1H$gvvud8iU<6@y={jqOserJe7#goPU5${1hRElP~$^# +zcJp=g11&YCr6u)3gqO+S8rI`1kQtgUc1|?vVBm$MeEe|VL~(e-tHaQ$2E?IR_@WSWZG+IyIO&Q^*O-` +zZLA#h@285X0|^b+Uj_~PABw*MKd*m@x^m#E1$^v+pBtZaHR9BVWXr7YGq+zKJc7O! +z&b0?Ja8d`i@AcGzJQ}RfIUAPOZaG--3xA9gzj3gl-JkEn&{#ORr~Y6fAH21bn=Br* +zbYAA@Y{x$CKs^1-MAp$OR0X@-i|=AiuN5DxQXiUEV?gKgp(S-9?ft#fh4Jsb2Yyi|+g5!3C>&^6($uxBB9Oz3*2@ +z=KWo@nfdA8yq^fb<|;+cPM_3=y&t`J)V1?dcTJpuU~pFEvu|d`@+E{@3cel;M^_+Nc{=p|cXxYatC4aya0Z8)|rOe&<{iTEn7fqZeO`?N9g<6z73)8zQx)f +z!Fo83^RBF??PnclYd*_X6Rfgl_JXgS`JS_9^gV~~^rJPq^N+qAqwlhLvTc|bGd9d0 +zSR<10tNP{4)ZWPErCwq+`bqHg$(E06x+?5kE(=+?whmdAp2wwLg=C&t5vp8Y-&IwD +z4HDEMUrjA?@5^0r$+P#cH&lmx*6-*8`5Qc++8C-_2Y(1}vIk!Wo~QZTGtF3-R&DP} +ztVSniKl55nSB2p7p6ZHA7yg18lP?H{Z}hND%6;2ps27)wv5qw^S-Ywk8-sXOwvDlC +z!Z`B^b>~#OTlc;H@Zz?14Cf`RzMb8}w%}}pY>N{gbGC)*BR|Mz+R0{S(>J_CU`Hsn +z8|d<_k2*V|0GU#Ne3ZP&pN@Q_rnsJ$T%G)5p1+gld)f)3I&EFlhXQzxVkf8`pLbGM +zJl$?OHR6BQyPc38vym~e6OOP6+7DMe=#O{e-yF8%i(dri&ar0Zd-wB9p#Q;NJNUDD +z|5fn!x9E1RZRVP-0d@`ZTOaQj(2SQRdg_4!H-;@ +z+1l@rXmu{XuOsrI(6!XD9nR?Y5A{vZ1_ +z(YCvb%$^ +zqsih>Ws(?FKlb51PJx9%^TopR!dIovfS6qWj7R)&xE~0zGd<^ +zIh8gBcU`ejj-d8o1}TnGfc-*VxOjil0WZ;jy;k^#t)ZfI$1Crvl}Y7bVpZG)GV$5Nqtz->?11e4$qj6n{A#u&~V6-QLvBk^E%tT%w! +z!dsAmH@KeO>;7B@&+jom@9#7Fcinh;(T(Xj2YuWGo^1a=&G7rpq7$$P9(ym9xi{eb +zt)VZJnCg9H>}OKzJDVTg@b!n~iFZ0Lm;Ze2zj{>`rk9mhrhKzg&4;b|r5n1hdC7of +zNtgelHUB-<{GF_M?P-7Dn!hL4U-O}?HJ@9V{D^D*IOe}6;JpJ7Oa2rbv|hQ +zi$B&+^D6QgBUu0Y{PiE37m6)o{pT^xxersn=cH6LPF_lC8@We}-@av}J+mtwU6r%m +zp2?OxkX%?<&XKg$AQQ-So(w-+^|hSpLfWg2O8+tB5Yu-Nbl;4fzG2k1Q(xR` +zs$W@?Q#}}XcE4j{4~}B5dYF?FZy^%~zz3?Mc+9aQI8#_|z6c!JLsdT37x~?Gf1$bc +z(h2-!U-fK$D|brQM!9QkcaJo;oZa|rM?&rjJ +zFJ5e_KLM;4<(rxR30z;hBvjotirn}u?wJ9|82RzKw}}0{fX}rhq)->RD#YH)7i&{Ep08n-d#^eArbs!k(QN_pW!`LT_v6G1jGW +z7v-B4!7D?sFLuE-rg#$|0l@r57xh~Y5j9;5M#F?D_0={b|3>*1u{Tw +zBm-!($zRW_=zG_T)JFa6fU;fe|30*`Uv(dN^PWozWJnNi9< +zzW0I`KbAJ11jbMC(b_+b5BQ0^b5bfI-X2bkf&3fhnLMvNcle1DjX6y^zdUzCDYi(? +z^||LgWU6(46163RHkXkLaN=uT#i0LS9nyB|t6s%o{Tvxjj7{go=is>BSyTn^& +zEisj{iT3gR1bAyW-|KFQ8R2~nbZ9c$qRqQg(Z*CN+Ool&y}BaC*{g7OddzyN4|{yQ +z*s%YS(f6k_hHA71V`*HCCz|z#j&F?2&`~t(2MxsseI)y#p=`}P*yfVeZzQ4N-G$~R +z(eQ50I|VeyTLvDXWn&)gg{k384a)H>6Q +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 +zrZ{^M$COvPZmx>P|iTRD9TO +z%=slkSQ{AEZw{Q7EEwu}9DVt=8txfstS}t~Wt{D^8M6NVWf;tqyX3FS_AlI5OyIb& +zUpwXBlun&VoBosD1e0%xn>8k5W1*MwJWg)~vcnvM+7gw6HFG3oZJgm@jU#b?Zhn|N +zC&}g*d^?qB;W}`?PXf}vZSO#p% +zG<1xzqI6xV%eFH+if>;Zu|;`c`uZ3zave$IMi)M|R{@r5Uzq_`5XJY}%$yZ#8$O+oAw<9)DZ +zbHvKEfgwxA##yjxpIkRs4H(<356sxC-B_ZrL;!*O9ZM~g9yeZaYZEdp; +zpQ%qq0z2U;wdp0qlQzxucNMJ5>aumGV^1&pEOBCuCN}l+e4N`F^@lvz8>fa4+a(1V +z-siwu+mp~ZVu)pV$nm*zV7bj;aRwBa4TB{OvF&UpSc;jn>l}A%c1+oeu-z`rQl~xU}6t$ +z1Fc}4EKL0;{NHXgJ#KEOyLBcndB~f(M7A=1V<%N5%=rd!+~00SLm2(FstIwsF*e!@ +zRsiGt&4W!dW1DWRruJSi+2hRR*W3ETeK(8N9La*g^KJ}bNicst(;;%5A#yz-a{XY) +zuF1+~m^cdAE|w(6KqNy)0+zQZJpVDUZK)%i>%Y8#k~LQo~<4Dl@K^bd2-b +ziepkIn6-oXZIcUOy^3*r90W7<&gR>sGX^f{aK0wN;^3TT@_h)=42jpINXj27aH0oQ^C{MeTTM^0@+8e><;50)7?; +z6I-y2TfpKroq+wb&v2~Aag22js&tr*`sL|2r#<0kzOrX|`b%{a{P|x5^OyNSFjGe; +z2FI;2efa(nxKKikB9}uWcsL4#exW@uY90E{6wms*KV% +z(k`bn@PABa_x~atKF0%)XFGC8^4HP)MPo64QQhp6b7X&ldJZ{5IX|xJEr?^*JJWSz +z5!0C$*F_HQ+03pBkAE!J^;gObXgS+ilfnZfg{*HEu8ck +zy?}Klu^7%~Gj*UE2~Kd_OkJ|e`qNy~DO$lF%h;In+=@7Z9EbaBnx~R5n}gjlGbQ3a +zDF?Y-RxVC*J-kp>$_-@O>G%+2%^DNctE%+f)!ETlCsoCD-Nl-1>$lhLsJmywz4iAU +z9bJx4O0>8y_0zYwZ_?%_z5soloHmVLy_9>l=|OOo;lQlsShH*Pg*Aft<&t1xdp?%- +z%VF%|B)Y)6St0eubnYG8>nG`FAC8&p2<$(xQMOh`22e<*PTPG`zuA_%5GQZ-QT^x1 +zyO~`XnXWw@>`s}sHxF61E2VAPO2_&=oklM=847&f-gEd%jelU~I30`ACjpkD{qnh( +zx>3^A9-=D;CiR^A++MH(>!Nud`MW&hGc|$J98qzYjfd#o4JP^I?VOT}6Wb5gLi?zz +z)N^F514xMD)f~qMgLY^H^XpHB$fZMAX9(*7L-jLluODoc6HnI_(mQIg6p`a4pUBQ& +z4{Y)}i8%gz&4i@45W<$hYB)U#tfLwOVYMODwrSe{wx5~!5jIuO^NzdYCk(%@s8!Tfm{29vz7+)gm5L(HbYxLt5yHX9Om5iHI^6j<(Hh+NI_ +z=5TQRTd_2WB*9i#oYoepd$o=nl~upk!Yt&b4=-T3fyC_WoV^E%#(C&dx|t1yurV;{ +zgHj|n31-$jvvm_y=l{ITmTOxTH;3#4np{Y0@pfQoZc+GWN4b7;y +zz_zcqPDnZXJZlxpbN;!0uf*w#0@o3`{>*b2LWS6YD2HaKaT-qM1Lf<1tiKtI+X~xE@}34y +zf|HYD%CHN(n>nrd&^S-didl;=$2a46KIAy3H;Ut?pXn;6HwkXaj@BhPA90eO1vmYo +z^~0hye946CFdb)|%aG}$eOiDtaam8zDGX?=;V2 +zWn1^CSD`j13;OB9>4a&;n}1uknDfw!_$iK`uZyw0GPFAcF4wKPf@|A6*GWHOMqXOn +zZMS^~IrY>gY+dJRD4!~)F%Ml`oJJ&NPL#`i8GN9Menit%CUr8<9{S1U9&4g63bl4) +zY}N$U!VKlkWzq(|H$p!$bveFXMwdRg>#_Y`G$R+R%xW|)shD*75cdGWGkBewSlj+=XQsC`*Gbn?(->cRd%_D#lzL(FaJ*&=kI +zig=utgTkWpgT^kpR%+|Z_VsM#3{|z2KoYj8MMr~)SV}6m|Hzz9Ula!Ui^dJgt?d$M +zWr)wcXy8WBOF?Gt!Wi +zK7)UDf)#aq>JUxcvq_n>1|ZwZvQ!_ays2s#LDQd+bNL869!WYp0of_5m+zzKk^3kj +zIiJ~}pX=Lx#Nj@M&c$Bm;;X?_<+%PJn);1h> +z6>(Q+pUx@8H+yWWxhF>JUtGXu(QKGwm&OZo@!E`4tQkxs$t9PvkajP&^tXS+?Pg`x_u9e>u{a~1)R_ep}2gTOK)AmoXRUGW_>6Tfc7(dIng3 +zByUcZ(_I4h+kns2JCna?IOi{3C$tkmGutsIK$znvAZOY(#(s{U3dWaf9TER|v#s)w +z%hNuk16xr?OCx`2JfJ?=-Z4qj7ZMvqoCfxX+G&nS?Q=(Mj=OsvC3$`9-VKpmP#_hH +zXVzRDA_oF@d#o8`@7=)l);o*8D1U7COkICfdRu+_)>v^v$M&OlG>krHOI>7EC1C1W +zip1Lxw}Io@dpLN$Z@P8va#)at7`l0dPS}p|GduzLGR#D|-ngPU4uS_4c03EBO4>qT2MHwvc8KHr5>ygZoSe!ofTwoMx +zIBjZ=R7$imz0(NtIkDYZA+y=$ue`28#9rTgZ_`-A+i2A +zCu(oRDs{zmq=);1Y3S;reL6?>J^2n5K5ULJ;&|2`5A=gEW-s6`jD56aRu9&}2PmZJ +zlK{hgc?DPd940H3hxB0kbJu|GB)?KK$#rHE^xeQf&%AEBv$WKF_`Yw?tH`O{k +zrsktKIsf|*$DAMiZlTW-*r@c+!MRm*T6|mI**2Qxjn+mR +zZ9Hjwob71uT4vgF4|JLPQ0+X8hB8_pp(f3aefhBs|1>0M!|0;>7@y}H(%3EeRp;3r +za-M9bnsfLpZT;sh_j8S4leUicSFwXYJ`KC}J!m#|-J5$c>t#rv$$9BQd~<(2&tp_x +zj04F9?z1_U`3U0m*mU`RLUT#ZEWeLP!dPS`d2Ww0h-22R+UusPGNW~Yc15#_-L|Dm +zS@ER8_|(;$SqlC9#lC83&W26#8|c#xT}H2Ojh2t)am-|q +z=OEmUiF4f>z_D7|=fLtsuqg&qCggl@yEo-EiDUciF+NXIKiDTMji-;v3WlAZE+I~e +z>lBSurGAGm8rXGkQ+3(q_2;o-y3W8~G<21wihM1Y99y|pxQPy@AdCK&=ZQu&drGF} +zunc|jkn6B^W*^op>~Nm#@{4iNGd$6wv3tN*8BA$$TDzb_>H@Vzb14}^gX!}*|NH!T +zqH`r*)L4k`T`Vp6lN^s9-ue86{$I+a+q#}y&*M10WY<)r96D^BjSe4DT8(KpcTjWr +zb|B8^k@SP=Im*r~U~n%NZ9j643}kpj#MFZ!#N+bkz~jXj82kYCn|itbp;4TNn(|0X +zvIF#)gM63GFZpvj>U!|X;<8LcDB+Ng%#U}rNn<>yRqv=x8d*gm9f=>_?J1a+4AKVYC7nqF$v=A?m|4{mvxx+JsLS_h0k7P +zB9j`&F8in*Qm`6q`}ifqZMEf*lQG3Cad-Pl0%gE9YJ3r&knN**%k3cvW}b=U>pmEp +zj2>Bk@%25dr(5Z%C)NknPy1wRvu4QWI1Jv$octrR&OpPi&+53vh95dhqF1zi+$`c6 +z`vm%}&CJl7 +z<^uYn0AHcpXGXgyHkRmNTRzV|$k%dt(Aop_n{=wwQv@C%!`<9`swsP_Y|lx=ZJ>P) +z+~>`JbuwUkn)_XC735^il~L*;S@s}gJzE#bd1Vi@)Ip{X=d|M7m?>oJ#*5Ro#m~6U +zH0wO2#}bS^Iw8}`{e9MVf4f~avu>`ht_?z-)8tT~&nTFAzO{qrX2lvRqx{{~_EsS7 +z%Cr6w%>BDehl;=;F^i%>!FSZJFtO>ZLyeT~sx +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 +zHSmrS|MKxWX&@HJhj?(|-1I}mV% +zZ==sa$YL#<=jf$JEj#QeUb=_7TwbP1n{sctjuWAN9P6+2;4|Gf(nH+_y`#jM-#SFm +z{%5+RXVy6Tp=&p1j^F>Vo!;28ZZy_)Z+-6WYJS}bFXpo1=tQUog|dw9k1FrWKZCP< +z$^oP$_UF3fUC&=Mo*qhHd}{=qhQ0ey)#1@~RGzMygz+D`%sXDq`g#qm+GMxacJtku +zd^WOJWmcVB%A$?c=2XhAt{L;n{d%19D{0Yw>G^Qq^+c|33y_gMqnp?=Sms&uBhAlt +z&}y1(w08MJvKXzYd4>~?48q#w`oW7%c7WitJ6}Uz6ngE(^g%sfaog5X#$lxy1&wy5 +zrEm@7v2Fx%=+}6i&Wv@`w~<$xew5dS&00ZeN!zY9&mtbD&mm5qMX((0oBoyi>zql@ +zROlq(YIBgr9G0QJ(fFY@vC{ZNYZ;|`7NHfS|f?%A)jS= +z83(%UQU~XE5XU(`9M}${Io_lB4S$J0X_w;6vstt>-lbi5XiPEd>*o5V +zd9$WDZ|=KRb1a22B01^@(EYLhA$^AJyAn58S?)hLa5`;ZvkYjgkg<#MRVvRk9qNW$ +zH~SkM=Gs{=8_S+bWS+!P*HOpWn<<}|$uHYz7xYN`Z6!7hhG&yg$OCo5=3+m2-Ob{4 +z8&5|3L(cyy;^t|e%e^!vZZ;V*nc*~=Ze#&UpYxwBt-brw$Z{H`_9`uv^PEFmf1Z2) +zKj@oK`cjm}Ua%=%Yhqt|YcJ41R_pvSy-Ggr49DTMd?=2oPK%VmpuAF)Dd@3}~K +zbH>R><1hBj>7uICZ+d5kjcj~5YrkH|OFx*tCzdNWYwk!Q)6)LL{pR7ZnLZPUyKK|q +z`zGlcKDBV_uO>^)rhJ}@kngH8c`MNMjCLNJ3)V^Eljgyd<}14>_QPoPl4{vUi&OOG +zn>bO_5qs|yR}fAt&6^Y*%R&bCf#!J5XkNw5`ZMz2G&S(jK0iv5<)Si~=K3`P9VyN; +zt$C6Ta_#)}xxCmbIpxTl{v6_Z5&A*zWGJvX*_SLYD$u)Vco->nFn&)VP0{LarY{O} +zoIb5_7`N6g`S_Q6j271*&U(6_r=gmD@L22cEqFL`>B&>nozP?ccOy$aO6HyzHE?@o +z_Pn^xXPhTRPdAm;6P|dImYnzwP=9pWXgICdE%Zg9DN0}er?e*isEs1w9lcP +zKEq&>)K1A}bbW?AD5|q}Qj{?FbMO*>|u(OFE8jy~wx$qISw(L<1az>Am2+uf!S(^&e-eB +zVObCN+ajPdNn&k~&4t+B+?POB?l!QK%||d6Fx^c6co1=`ZvVY||`s +zartma(We{C{HF=lmGz($9oM2L +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 +z^Tfx(c|mc`Zq!qY!#Ibi_a*F=H}GhDu2aW+cS +zQ;YM&Z2nz*qc@=R$oa-T6`pSH)8Ty3!4sbemv46PIR|eX57#r`;KQE_%3n_XHs7z+ +zy32C&-v%Z7lsVgx!$Xj7{DPHlf;zE}a4Ri#rsv!zg6WFP&p07LftmP~i_4YXAU7X&}6PoTf9C}=Qqc^SeNd1rB5j-#94TIr) +z--pBb)Yfpm=-_?#h07NmeAj2foL4^-&Ii8{&TGFN&WGp1dHo~dy!b>o +zZxlxiB`WqG`+2y0)33t$#P7m+=1<|g_K;|x4oSMRhlle?z9CA5sP|1p?9Zt8FKf8f +z@8Yx`+Yr<*`RO?^oR6FuJ8QVjkBig#s>+Y#zxuhsd_IP8 +zZ8Nxeewpks3Qb7M^eQ?8X6+7cTO`o125_^6{wmT@edxqu%!dzxjvNMfOjVDC*-F7(pQHGH!vuQE4cB=rww +z=LWAY*o}Go-vw1(na81VFSz-?CSs<%X*&l#4n56~Kjbj0XC9oIrwOg#i{P|8Yr-b* +zB_-bnz6?%ovk67;6(#?V;8a;mpr0lzfXBck-9La!H!1SRuebS6K)w-rUIK3ZmxLHD +z|9V}-Jzi&4;btRW=5V*YcYvE>pg6L<8(j3t_6y)~=ok3~@C3N%uQ}Yd)1>0(fy;eG +zB7YrtO6l(h&nP`#2G4@a_TRwAl%C&%k1KvERV40DCcxv^ZUUdfZ#lnyaJjBrgX8?Z +zMYGP26B5qvRb*ZRF6a9T@EAY?^c;1Bl}{-7SAZwM=`yzo?*VTGmvlc4o>Kh#;2EVq +zQfJf6Dt-pITz1A`?>g`<0Ljlz@SNg51DAQG=&5^_O*ao9`ELO)DE>o4OS(S?7dKfrH#9ECX~-9lE^ngV&wanjyHR>?rw*r)9{NXZjlHDN +zU*^(2STO26y+%H3^lVzguK_RR8xpSqHydB9*MLj?lSAF$aRJ!g3Z78>4d5xo-)#5| +zihABVAfH!9`oa4ZzYDxm@ehLcDgO81ImNev7Zkq-JgfL8z=stdH~a=KrT7;hUsU`{ +z;Nyya4SZVhJ>WBnf6MS&ytv}uh5Vx8KLlS={88`*X%IO66!@}|{}1qfCI1WXqT;^- +zpHTdF;LNCt%|=CyicWj3HY$$mxIqJekHj0Es~#2;NrIkzYbjd5aF){ +z&jj6M?^f`v;2Uw;2FiYf#(#z54>OT +zPl1mq{yFez#UB7)RQxO8o;ZNW|3lz$#lHcbQv6@RrxgD_c%R}w0v}WSaqyhtKL#IG +z{HNgaivJh5Ck`^s>(}5(#eWZ;QvA>01;r29zzR2c!-^jcKBM@N;GQ`C$j>q0NyU!` +z&nbQixcLt*=-|zB!RM6xS>Wb>p?&h_f|nd^9J>I#p~fdnyBC6I6u%U_Pw|(7k15^( +zKCk$z!Iu=j5j-vv5oGID@Pgt6@L|Q@20o?uyTRuae=m3g%_sa}2t1?sN5S)oZwD_b +z{&DaL#mB+*d-cBnzO3ZG3?8TXgg-n4o>hD=cuw)}faewe0r;TekAfE!Uj!dh{HNfZ +zG|%vdUxK$P{u}TH#aF@gd-9{tX04mNd6n*Z!*B5V{fW~4k&qu(`WwKP6h9GsjOHu; +za2j}@l0O5yLCLp(CltQ`oab}?a1r>R;+KIBE1ngu^lt*!@3+4md|t`l1g_s#-(&b~ +z{w$jPHyM7*nkU!od#g8j`u+BIK!1|vVg7IzcvkTbf%hvu0zRhr4)7_(KLNg|_-DZz +zXujnS_I=r#yjI1(0{J<`{|UTL@o$2c7D$lDEI7}%{Nab-ImI6XA6ERw;GHVnCGZKw +zpBAq4{1$vk@jrq$nDMZj)9QNOC;KRVICxI+4d8u>9}7OFcpQ9D@zcTMravg>=S=WU +z#m@!rSG)~ezrX!raND1i^=|~9R(h@kPZ~RwAn*@q4=HPImO=(o>zPrJabf8H}7o)pHTAmf-frmDRBKB_+8-oeeVx~536*)3O=Uz +z9`G5(XTTQ~|30{WKm5bsv7>|M`viEa;`_ln75@czQStuMMlHlV4}3+*zW{tj@m9lc@CNm~67or<|7GAg#a|9S +ztau0bl;W>8{06?L6$m#%enrXO3Z6MOAnw_Exyc(-{B4krJtrvtZtzaU-wQsa^bCRb +zEBTLt4=cVMd`$6=gD)yR4qkIyFrQxlk176T@QmUQf%hxE7u@`pxG#zCfDbGAAApZ5 +z{wR1(aocWby+!e#LcT#RL?G>7f+rRK4fvqqtKegbM@>7VbQNC@zO49>;IZRsF4Bn^s-Qa_Y-vd6b_)hRC#XkqWsQ4Gb +zR}}w8@cc<$AWVbzDgG_+DaF4BKBM@Lz-vwpsP`7YAK9;PZ+f2VT<@%+JZ-3B{ia-lupHyr}s3;ERgC1bjvD +zOTY`K2J_PnKCJlF;4_N93Vc!V8^AkH3+m5<=M}#ld|L6hihjl41>S#pQ2zk!2fV2Gi@+xozYu&*@eKH);;#VjKO>l*SArK6zYcs!@ow;% +zGlP0w2i~dpo51smza4y8@qW>NR#5-@z~hSl9e7glkBNT8N5RdX0sE5pB=~gF2Wj_y +z@HxdF03UuqP~Q6G+f+x=j%I^bDDgHRP*AkTf33yELpMm!) +zZvV$?lc)dB;&+grQ}TZTUsU`MLU8KA#OV@Py*`fv+h3Y4G?3K|P-b?^k>hyr}rs +zz#H0vdj1(aq4>Xo7ZjfZ?^pa0@F~Tg1fNsw6fLsc` +ztn^#~UXu#u^BVAZ#k)k0;;#kozc8rhHt?e2Zv>xKybpX{@jJj{7X|g-1)fy=L*NC) +zN5BUa-vPd;_$R@qYrJQ~aCY4e6l%S@5LdKLqbn{4wxh +z#eWRGr1%oJcS$har@=Fd{}w!__#eTi6|XkyGIZTd@x#I6FAJu-0lZc5W5I_NkAsgX +zemeM~;%9=dD1I(@_R?T}+Q9RQUkpB>_(t$)#jgaf$prOxf;TAs8t}a0H-q;p{(A6f +z#e2c$6n`gp;<8|V?gZEWv-5uNF(q%;?>2c;if@JdlH&J*uPFX0@P>`S{OkfxDE=UL +zO7X9PXBFQAUR2z!OVWCR;@^jS?DAlK9tMvq{sefR;`_me75@eJyyE{2zM}Z=!E^1w +z{CJK0dz06v_@Uq_#p}T1iXR0&rg$TG;^o0~PXW&={ygw`rRN3U{Yt(SoNiSOgqMPk +zEB-R@CBQuLqw{{7CR=#T&q9 +z6h9GsQSsBjy{m%fdj@!e;w|8vieCV({}<^Z@IEDf8Th#3_WA_*)rxO|{G#I5gRdxl +zlcalf@Vt7!TNQsZc&Fm;5dDg80WT^(2tJ|shrwqQzZ*Q&5zOa3;C+hk1RqxXbKtGl +z1oeCoJfrwOf)^CG*L5~|(~5r!@-vEm4}4DXAA#%tOIiS5R`UN2?!7XY|DS`$75^1@ +zQt=h=tm1zL&ndpnTu-8Qr}z=zi;CBS*U*xtKO6_1RQzP{oZ`;~FDP!WlhOK*;^#wt +zMe&!2{!V{xJns_lq~h)1amB9&?^pa);Kgf$`fmWAP~2Y6+vF`PemmqFUKP~yR`Ber +zgZy3KtxA3XJg@i%!HbH21bj~MZQ!0tcMLqK_-DYU75@kDF~z?GzO49e@I+Vee7^zS +zsra|SrxpJ<@Pgv=;1h~J1-`8Ke}X5j3+Cs)z_W@U1kWk{2k=3~BPX(6ny)E-7HjWxPVs%<(~3V1zO499z!R?x +zp4ZO||BR>HQg0c&5ES=*2R(gC&!51@6+a}-3aA}*2Nl(VClr4+cuw)>fcGnY5_n$m +z1o*h(XMxWtejd2~E6EpwCvNfrAq}2X{Bpx51G4<%D#IV}a{R*=u8s4L2i81Sl{0+O +zOYmV|xFya%COx(6;l06dx*t{L=Plr!if;zbDgGYtF~vUs-lzEAgL^l7flvgWSMv9P +zCzSlB!E=g#9z3J?BzV8#UjrXk{GY*Nw|If@ui#0==fFM19|2!d`kw^vRPz4;KCSox +z@P5UA4L+v$|A4P3UUia3fv&IRd0P%O;Bm#D1>ULn(cpQ-j|bQPOV|WHsN|my-gj#` +zFT8iQ;SYGNksyB|RJ=>{-xkczYr(UM-v(Y#{Egtl +zirf2^X#S%39gt7FE|~6J;5ADAL*Ua&egr(F_zv)b;-3K5{}=gL@D(LL0bbJ+%;#6Y +zlZyWncvkUmf)6V`3qGy*55boee+)eK`e1&33?5f}2|S_r)8KuI{}w!__#eS%6t6y+ +z^FjAXDt@@(^ggR|g8AG4KC1Y!;1i15`_eXgdlf$&^7D$H3Er#tx!^g)+ragD*Tvv@ +zF1_D?$CRQ!fHx>!bqa&qytv|r +zf+rL|0z9esvkg~`mt>9wuTk~8UC3y{7vB6{%<$@{x$Ob;M$(=GyDNB +zSrv@(ci=(lc^?BWssp3o(@M`LMUUe5gLf+a0C>ORQ{ZEYe;s^9@qaP=o1QM0?}B%# +z{O<#wQv7l7e#L)cI4#Om2M;VkK1e<9X>i>xerx!*wYc|3@K$xCx{1Me74^Ks4X5=t +z)x%Uw-7QEpNK~-_^q~fQ8rxfSdQSX;QCHNKfmK|IbR!KhMkdHcewSynx;OiXx +zPzTq&k`;@3hdJceJNV%aUhCjTIC!0dKg+>m4t}JAZ*cHuJ9xc=ALZajJNPjU-r(TJ +zI{0%O{5S`1bnxRH`~(L#i!p1CMZNeM#vtmQYLjUJL)~pq38Jy-t6FKIQW?kewKsl-qwmmy%#v-&vx*09K6NB&vo$g +z9Q=F-*S)_Li+V3~$iK+JFL3ZS2Y<1Hzr?{`>fk8{ztF)ia`1~CJni6@IQYvP{89(c +zIQV62_?grcH_-nPXdn=rh5(}i$; +zF6d<6YO?SR)CHXEyU9WL#fD$CMt`s2SFhopFuY?8|B>O>l(>vE5$a-2_Fc@C5$X0gyO5J@B@l}9$em|632P%b@0c*<$WoVZuRr+`PReL6#K`)+rULW +zL;PeA`Qm#X5hkEV-mBkoh|TB$aCtxfPUQc*X4c<@U!J#ksNKDVIG2mO +zCw~zY@jfGeeM!FhFuOYsd3k^SJb1$yR!f+3`LJJl4=(-5tH4*3{CmOWJu{N-gWz#YIN4h@-9|i9Qe|C$_r@RMd +z75qBzRZNY=&hG_p#?&|i`7eR@f_K2qKLMXX!AkvKf38i}K40j0tcncgf=}(>l&tS?d=k-6}ec;lrPo$|4*Z%{UN{iiE!LxCj +z;2_d{g@fM=J`edcIGNpqbHJN1g%>+t +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 +zegC +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 +zo*j<)+BFJX^OS2sa*Yh#sYxXGPLHJ7DAo +zjD`Ud?tpoAz&tfzGz^$$2h6hr=Gg)BtkY*6cKXcIPM>+)=`+tebQu^0NVzY+j0%Tt +zLNd@Oar#7yx_~-}BU;ou9MR&47Ig>p2XP3;5iQ~pjw`l^Q#j%wjyR3uie)Z`;Chl4 +zPEsC7O0bg6jw^O1d;fPN<;*^dj(GrJr +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 +z0W&;o#t-by^2-ZX4eScrPB +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 +zd0;-+NS5*2+#%-xr8yP@xEHPvIv>^6!% +zvK3uj)9oXTCLg2HCm&YR)3v>U2g0_mQNGCjwMrPCxu&AVj=}R4w0)4)aQU3Jd4F&F +z?X`8@o=Ls1a+_EV$NgcI^`RF7k*3h*TL>8%8Rm +z(K(-@lt~vVk~P{)7P+>O@dtNw#|`z$i!{m5zFN#|zJ--G>K^l@V|-~V4Up({zu|m~ +zGMhXh!s#O=od`)+Z$dQ-6|{cgPufN;ub2w~TMgaxA$o5uZBgA`ZPMWg-4Po+kjj&` +zEpmY7arqEyrPe~`-vuf#bel>W;ELnjQC(xCkvl5hqH7=8N)$?R4X*9BSaLoMDq` +zM46{8-xaf7M;Rg8Eutj*<%&Bs+sK8R8(MJZx(Y%K%Wx+g4b#2pk>=6Vj4x^qy+;^E +zS2xT}Q5k5`87eNeG<)}&e0k2a&yhMKrcdUgko9hzxN| +zlg*u$@oH3U=FmmeHNDbY?^`B^ema~be4}+xkZL_@^zse5BqFj9gjbTNFT>NhG@O(A +zGpf0uyQOH|V|=DaZ+xd?n>6We1`@Oq9dS`UwH{`d6CCsm`%-8MS7xOBDO@@I;g>;m +z;Mhs)s9iI50DZjSD5ySIU6~Gpp552MIVE9KHq#vEtPUV)BDPp>4d&bOYI)#gyj0_v +zJJIRcT*KU=jWvH-Dt%K`%hJ5*Ut5#r5iUSQS56cgm8vCQq4N{Q`fv;EnpJmy3xT;W +zc2{NlLX%x4luYAfj!JyqXWrZ!oZyKTHVPt^hl!k^WSu$e|RlLk^AMi*Kh8d +zquFz#j@~06OKY61vQ)Y&A{^6M(~Nax`dHO~Ia+#DEJF(ud49om#8BLKhyBzQiAeUa +zO?#?4Xd*={3-7>NGac4QP|g^a&ovhda;?(mt7u`(j0m(rj>BUDzq*OdgN29z!WxU{ +z{-KG8&QfUkoc2tbx29`_@Fmyc0Y4`KjFfiQPUn5^;t>k?4y#zdN_2+&Y)ENxO%66f^S%!z(YuJzGOI(RY%%SmZded~v$iqFyOeq%Y +z)S)sqNu%~(l(6E^+H3Qdwy=AS{csv(2M*E%zFYI!;Lsc6G{o==PAClaLEPD4yej?y +znJtZdAh721FzrF%hiJz4dN?#kVD?O#N$u84KK#bdzl1*U4iRct<@HI~HO2U~CvDZV +zqeUB3KScs&(4ff3hAi-<&2czgtf6TK8JY3iO>Vl*Z|DovTTbhsF>goXGsUJ;^01P$#ps21kRMQ+pf9;p=T=H6fatH7^Xh>k_XPSmv~ +zk0QjKq%0x%x3+0wsT1Q{^1?&VKnn;L;TBBCCAo*Xc!3%v*}68DXSO3+`2XJxiql6Y +z$fU`Y@$y5Q_qi5~}(R|b+wNQ`LILeSzGa$q2chPxGvtZJm#Sb6qlc_77 +za4>V6`n-RO0__=~xo7G9T3=C39rc90l__G><|{WBGpun%gY#cEZhO=qq4W0e>nD7r +zdbEy9J~p^i51T12Ki%{VSOc6j?Rhk~Lc+*PeZQY%xY$QM+aAK=vr$2DBTd;CA6O^= +z9-*5f>g<=H*kBk=>dAWbh|B?-ax0_VKmtGvV%`?kpuW2<@dt{0`0Zo<)(lON2z^7k +z78x&Loq_ZPGkd4_5)*v)ni->pjiAA{Z0Zg~b2dB9*UGlD%kLcV{#)B_?FN~zEQ3RD +zr?a083s@Qgy(9bS;Fs2uv}w3Ht=l$CPJ(X*Iw7$ukAW6DMHda`qs|osXY`U>xp1o) +zZsG#!T5@*lnw<&HB4a;;RmA +zh{^~{TmQ~7o!XJANLCpFEtAtfM#uiQHEC94h9(_p7D0Do1`07K%&`2!#b{_QuL_jc +z{YBP)TAS-!J6%Ryr8m3sIU@*;E(qbJ@UbH$deaQ`s+!VnhbmxrM4m90Hipv% +zt2X<&Vj@Jr3=AKpp19egugARo{7hMvMaHq!h`6qV25&!YH$8S^A_Hy>h}NylLq>cT +zof@Trpof@4$)F49`eZT{^W@&T)%Jx9fOL}d+)3B^M#K)qaFq+aFqb%zf!0H9;*T16DifcJAWAk$_*L^*mCfK_rj6hHF(C +zoP^Cr^?kAi!ON2olCrd^@oB#`GZX{PXekDHDJ~dOYpEgu79|Sz{8SyasVhIZhorJ^+9^akEUhJOvS@P_g_4T +zR2&C=4#C!qp0VtC#SUTQ4&j0MMXww3majwzz1tPKas +zt$!SgZ%8ReH;goy6iAxP&`@}Lw(c3GEqgJ|jMcEDjV&ZD8+RgGWb=sB9JA&{EmP)* +z9KRSR@OE~6ZA`0oWX>;!U453PW(N2=6UsQ+a8B8lt5s`eRj5#M(b>ZpmEz=sc8$h% +zq|JZj_`zTb>7tuBkIAdHyJIjq6nL6i=m^K<7{JXG5FBrUMm_!p4c=P8gG=2!&@TEE +zThnSvV$v*P>$Ug%cdo`;-pmG&BYdxZ;2-A8Rtrx@L?97NYdyYebjpbt7X>`p}wNS{fj!!Ujo$=I^zqOtZTk!P-KK0bPI~Uul)H +zmN68dJQ($5`^myuPey!6PnyO#%FyU9=m}n{k9r`EPgiGoJNB9>7M2O^L-glADfi7{ +z1;6csipfJ~R7vLH3xrYIa_BB*nf})h%~B!FcK&}}C85_r$ySYBvj@2vXl>o#vGXq4 +z+(IyVTgU7{s=mAfG`l8Ui$LpZpTc)sscUq*&}{VEC+#hVe4(*Cp{L{z1{xIIl(eVX +zx(khC5G-o)M8LLolw;#|kRl$D9A>(lSMzt#Uu#8wVDt?~hAY#w46utfK$^uCZ)~(U +z<+vHabxON&CpS))tfX?(P;#{sFfw{a3|%ozeULr0aA#iCU8~b-7H{G6m-1p=`e +z*V@IAG6i$^VEFK1#1a-f%QrQe*-2o0uhj5p$)W#UYPphGdQTST7lK%d|$J>09@)3&{Kt9Pay3Xm@- +zXFWZ@XOy!ZGSY0!iGL5zIjMPet1i}Gicv;AG5|56OU8pAs_h<;no +z=!@Gt4f@Y1f0DjNKRmD8_QOk-{3cPGxNOP$eASXy@x)b2-siVs@!b?7-xDLBiILwLBR{X4{c{-d<*0J@6XYji^q-8;e+J~Mej?NF6_7`M +z4&(#=0P@H;ZWN_( +z1nI+k3hW%(Y_Q=4;Pb!_06zm9^;`nJALQ@H@Uvgj4j1L`0RI%^@1~x%Jn}{0fpm-E +zoiA_eL3uBRF9SzA&jGJMe6IpWJ3GF%9WL@o;HZBlhMxldEQEUxcnx^xE85|r{%gQ7 +zA8*C*4ZUqWsJ|OH>OTn_<(Gk@{59Yxe-k*$C%!J)p7p>{{+RM7=`n7nR^;)-apfZx +zzYTi!ty5w8Rr`ARdprG_2fhLvfKMwqg@+ax*^CDt?URBQNiTpa~IRScZf*$NY+yXtw +z?|}UKDU3c1`!2`__^U*K^Xo?;+ZZ|0L)+2OQ3LMS@Bd<5B5^lH{$7myq$^Kyx?%mcqTCPn +zz6NksxgW02&s*||$K-(vmb}j|Dd%v15z^r{@b?1mONu_0e;@E6h%06!bUS7Z2H<#xW`Qy$9q{T;hqQmJ;47QxCb25 +za{~C^g8ZcNCn=btQ2)#*=X67Ud9ZEIKZ2g|ZEb!B_=6a}o)efp94@xw8$zz8CBn88+fZ9{EWQkUqBl3&6h(^jrsy_KfUm>-krZpNQe*7=8ly +zXF$)A@+T=6OrO)r?R2}Y+^&~yD7WjS+sZi|ehb3A3;ff-JHA!o%lfgO)~THJ{3gh+ +zSI*(0ya#%)f0zMz>U81de`t5%i!vx0Q3eJ`48W0eR&2LH~Y`?_dS=VSD~N +z@J{7V636njUODF@@~#*?-OBkF_A53ixAV6b^k6=21&;O1KHxXO{^c0n#R1ZX^kQ14sKi#z+Bu*v?mg{hi9$PUN0)4!0NNYrwHw +zH)Hf%P|orFD8%=Ya*i+ZE1>@yAl#e4p8(!9P73J5@p6FoDCc+~-=du3^(v5G0-gkZ +z8Mp_0<1?gyKCB1pr6J&0f6fEPdiWUdH0Zwvd@Jz8YfP{v+;0Tl3H+OZZvcK6{AZ(b +z&KEAHE21{hrF_KVTR_jZfc^sT4Db`cF&)mu@GHvMo-5!dtH6IB_;uxMC(7Rhj`FvZ +zbAAngop+Sm<@YYgW4nAG_)bXA2g>d8zW!MXkUku*KLGnTDrftVZ&J>7z8dTt0zDrC +zJ)@upc{WB*4LJJMGH}eV%Q5^maP-^61Q|{rwjX&{4DXBKSCwg!CU&&i4Ev*fXS@!$m$CqbD1qXFNvFM2wyS==nI< +zQv*H7mtyo>i;=$>BY#Udr^6>8+}ofB`JEU&iPw?>`mmm>pr=DQrzi4G<#xVo1U-KQ +zdb&Ul@@|m-W02nj{7-=Qf*zFb1CH_@aI}9=xov+ohED?D4t}@@9R2g8a!$`{VE-xQ +zoSw)}$LKi=dj1sjoC7_`&&TMw1RU+Z4f-*C?g0NY2=^}VPXfOO9Mk{4a@&6%07w0a +z@1TUC56h$e4&bQ2Q#q$Iro%?%cK-Ina4&{$1&--f10Klt7=A&yUA`^?zYghn3HYA_ +zzYP2@fUhdI)A=fJ)PD^)>c0*g_1{%)r|0@f&aH6$yb(C2o2Q)9;V;4djB>Ug`5?&O +z0Qn)1M?MN1{UNK|wtoWj{}t$;1U<<2#psy_Jy?#80{`!ze-Zfq0DeL_rvu8L1djSo +z0Y^QTl-u!L1&;Z04LJJqgBZTyJIO%$uzu9j1swHclykn{g!pb%&hbS)7^7!MxjnuZ +zQErbfYRWm>{|VtXm2hH!5y=WvnVQErEO +zH%9*h(Em4}zvFdc80$yAQMs+ZOSx_TmKZ*&oYMj4C$k`rd{Q~5!!5A0pq%YQURG|~ +zSp$yq)hoastRrRmIjh{Z^PF;yFWPwt^b|qQs&cmfZ^8cC%GrM8cR&yN|6S07^Dy^7 +z5ArQJi3q0y#y11}9@sgfobCJ+*jWbtcfgM-XZun97;uz7p`7i(@!AE@k9sZwM?I^c +zALXwBNBJAd?Qrjd{@W0*2f$I!`h8?LeK@`-zi}T^;V9p|&tOx(VSIalk9LX-|J<+eQ&z)^mmayuOg!1sVXr+{aHpHa?s{yn7I3h;jbenC0giSn0#qx==+ +zww>3NbGZKq`fmV7J-3x}xF~-YILhBwZim~OCk6E3aPL64TY&!)a8Eghi}G86qx_(9 +zJKQ1A|IeU*1UTx+f_{{r0FLsL%I$DZg8qMja8Ch8Jxib;<(Gk@{2AqTxGSLlE`)m) +zIO@3o`ceK8aFoBS+z$5&=>I_qH}e?hHqAMJ9^}_S{$Ih)8^He!_#M!L^7nwF`~&5- +zorx*2i~aC_f&LEQsAr>c_Cu8K29EMQ%D0m|)>n6xbGY{)+at;^e$AP2#gmOFF8Q?SP#0LI(K{@vi +zah>I&a_%1@zYls=K~G1KwaGXLxd$BAWirZb{iDh`ef}NNAq)IJfKMvt^g;OoaFm}> +zZl_OKIi~~ef2b*EJCPq(&UStd>^T8E(LrD8XGuBRiSo<9QGP|aZRh&^qLBGMNdK&I +zwjak|ZvKW!#xB1J3GY&{&^1g^MIdM +z&iV2Ju;&8sb-=GEAF<@G0!R7l%56JuA7rbfTtC(+fAi19L-IGv=YStANAu$`JX2}Q +zqyF>2QUB!_eoHy~|I62jPX2jYIr~5Iqg9cy`OTVeju+Z<>h*1o_MB?8Im&06ZI1F2 +z%56I*mD~0l13d*u=as{4{TOb~kv7M0y%;{O+_q;zxoywLyyy?{Hwb6{>;yj?1&-sC +z3FRY}{663)Ur=uQ=lB~XTsyzkAC2Z`fn)mIiQ)HSc;>rAKgahAAii6He +z&jLsJ3FUTtCzW%4;d!5Z$~j+I%7lQsv +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 +z%113euAKd$4EZvlobw%dK{nZ1Ok#ALQhdT;- +zDxfC|dXSID=qZ4nD(IO3UIX3){V0DFILa?7xAW_ma?UTj5B#`tPB-MIm2J-30Qo;$!%PxqgY0{Yl?PAcd4HX+=7 +zz@G)l%c>~z940@2C1$itl=Rh9$W#w!?mZJ@ylytE9Cgrvt_9(Z@SD$iD +zH}uaD(2st;FNQD1@Z-wu@_Pp4vAw>e+%DIbfnzzns+{e|a(x{*%HL4V>4xhm9oO6G +ziSg}@;a&{is@zWJLFINjOenYWYf`zLF9qecKi>oXE$bvM{PVtYw&%0JA1G&gkazq! +zKPBt7Zv=l{ubk~czCk(L^E;jVq6X-$x8PJ2}bSvmVJ_7RJ +z1>uf@Jo2n^ju-A19S4r_Y63qC>3meVo&Jl;?et$(&i?Qwu=9*^PJiSp%I)+&3wpjA +z^qd3!0Qy%K{~vpI9N+Ff-~T_39-p8nIxC8zhq9t5I=bmTdYqWdf|{TRtEsJ{wr=Zp +z%ciWRqpX{3>!u^Knv9N`+KRHUj-V_kf*>rMq6jO3;(NVLp1Hjr=cU)}x7+Ra`}3FE +z&Bt*+Pp|judR_19N}A@=qCWG7aONv=TbI|-5$dmC-74zPk5Px`w<))|@%z^&a+@1{ +z@>3B+59{ZBn12e+=aCtB9{Y9~&hK}x$o;wnxt*_Z9Pg&w&KG?P^|`N#aPF%T>OUX# +zcTt~yfI5dbt}^QI=iVQp4n6tlsPX9G=ie*$bI8bT4lh8TS-H)Do|D`8dJy`YLmj(* +zhoXOPk9pLgA0Yq7Sho!4&*48p9p;bW%-7_8pV#5sCk?ruPfPCi$(h{mlQ!yepPa+F +zPX_9pIa!|%!TukT+j)F1<~)r2f5J!P)+fJi8kO5|vCg>M`e%Lubyjg+CgCrHPooa= +zGjQf}ay#Bx^gjpZ92Vd_-YvNu@1LNbBK$@0ZMhvU^CdX*yK>)W75;3TuNs{FH{k5Q +z1?T(xna@NGMh{!}F{r;Jx8q&IaV^X3xacdWlfs-g;T8BPoa-h(8x@WozMl~|>rB9( +zg!);z_5Y{ne^ze&)8|l!{coYpi&3YDI`mRZokKYLZ@}6Az~^iVo!3_{!McNT>z_U> +zx4E(ZX}N!0k&@eW%GY%nxy@}I>t^M)E`3&R>+zHs_aO +z&b#oJ!4Kp%f94P2%pb{Z4!rMG;XJMyoc%ZC*5{w0pC)_*-jZ9N%(vmpCq5qqqlfRa +z2hKiw;q0?tZhiha`Wb-#1$t!Z+mBC-a+d=8N*nuFq{a``m%E&po;I`S<8&AO33i +zq1^gp{s_+evHY^@vj%6M4Y@tfR+G^mdNh$||0i;Lo@M?_ZpZZx=)Vo$hWGq;XCXT- +z=6m7H_scIwdG6-{IFD;cZpZau9M>@NJgyPB9T)TCayzcqp#KT@Kf%B|1Wqn~5=4!j|^KAAs(GvAW?KF{Fn^Bm4Tdz#UL(Zl-u +zXY`YVzX9Gaw?3I4gfl-Z_kE7Q+2y!C5ocY8T +zJ2icuJ#hBf3umAGa_jTo(9ZyTA3iL%KA9hdGe0i(eNMpH=MftjVv5*8MN^Q-@dKCvxkP`4*h{ +zw%qr54riY|CsE<(VR`o1E59c452K$x_($M_@|4RD!~lhH_c6ZzFo`_- +zpOV{sjQOFjpe+u4~ +zr(8bqRIGp)Ox$kod&OTFc_L-4e +zpPxZLGw{#Cb8_pG`FS|=i*n!R5}bYJ;p}r&Zhd|Z{j9+o@Pgd>WPS_I{I=ZpS%S0A +zT{!#Pms_8oM?VMfFTg8u>y!B^ocWsE_gROt&nBFGp31Gy|3*J8coTjuw?3Kg`AP)Q +z!<_kEx$m~lzNeSQ)B48y+!ACp@@%um3XpOX7Nr{U}~4QHP-a_jS2^pl03 +zz~|)FC-Vz%=9lEY&t*9KT!FLCHM#ZqW%RQS{|bClZhbOegfm}~`#yKz>~jy!J`d#9 +z=U35B8GZ^sl3Sn5AH$ii%YB~>IQu+-v(J{?`urODIfH*4p7?4Mj2_k}^GP`KeRAJt +zKb(CI${!ikKTg_8oyQRJ?0;BpudkRNliP891O1P~Tkt8l9T)Q{IP)2~Kdu=#k82jr +z{^#V@=Qq*MJp5bmCAsy+pHs@(Uv24|leaQ3+=w?6*|{cOR{;3c{B$^0&y`F*+X +z^8n6158>?dNN#<88~s$_-+|ZV)+h5#IP<4+-)9TXKHG5inK+FWj2_nKchOG|ybbS@ +zTc6Aiz?mPC`#y)^>~j>(KF8(O=l9Uh1pNE(X}R^ud>YRDjNJE`g|p8boPEyAtHqMsuCNAMlF^~wAmocRN}@3RbNpA|U! +ztjev=AETdRc;d?FU+U42Tc6CIz?pB!eV=D=_IWOUWK^Hu|4MwV(}2}s|2^`w%lFCc +zxNd;{`{7r>hvar#%#XmCACvpz8i(_^CgJRVT5f&b5dEa!J@6U1^~wA!ocTGq?{gl` +zJ{RHab6IYEUWtD4@EgI`X?81}q1G)9d{2`qA +zBf0Oh3TK}+IQwkKtAWWEh&KJoP^7(INSJ#hBf3umAGa_jS^=w|@l +z3m=wSpUjWKnID(?J}2Ppa|+HrQ*!I`X6Ppkzd1ZBw?3KA!I__z`#u-o>~jguKJ#+x +z^A_l51>Of=ms_9A7vRiq$$g(iIQuNY+2^j@`n)Cj*@NE-UY1**%va#dSLMFXV>tV) +z!`Ww3ZhhVw{hYx2;b(H|llgNv^F7~)g3-hGnS`^?J~;avkXxTWg?zX_Bjn_pJ}=E`P1kp10R6T%B@f4=itmQ$bFxSaQ3+jXP+x_>+`ngXBB=s +z_=ep2WPTIQd{OTE+=jEy9XR{klUtv+M?d@ULHMEE`egnH&it|5_gRCp&jy@*p2)4w +zJD{Ia_#NSGx%J6>q7^~(FlRm~_kH%l*=IkTeGba4&pV-?A@~q{RBrt+KMrSpQttbl +zg0s&QoPB2G*5{qk&kX!7@SNQGWPTpb{G#0VxddmQc{uxAm0O>8ML%osVR%7qeKNlV +zXMS7m`z*oP=PsOm?#r#utI*E@{BH1y-1=m`3TM71_kGsk?6V1HpQm!`^X}-U1s{Q* +z%dJo5d%hV#^e|_>SMK}lgR{>8IQtxuTc7tpKf~~Q!pG#+5Azdn=BMPo&uKXOOvBmd +zjNJPC8T6BdkHY8V)+h4|aORifzRzVi`&@yu&o#OAc`x*{4!<{iQ*M1SUxYJXlKVb) +z;Ouh`&OQ(1*5`fDPZ>T2KayLY%pb#}PPZW$E)+h75aOV5v +zzRv+T`y7I^&k?!x`E%%J6#nz@3Ay#j{1lw|l-&23hO^HZIQyKHTb~a_KRNgmd_it~ +zGQR|8J}>uuuE5#n8k~J@$gR&`KtBceWq46;eKKEyGrueMeeS{8=K-939?GrHhoPSe +zd>Vc%w?3J#!9pVy$DF?b3-DYrhEpN2D^mis<4aQ2ynv(KE|`g{cXnS=i#d{J(FGQSLGensy4 +zT!pjGbvXMh$gR&uqMuE88on*JKAGQvGruSIeeT2AXBo~uD{|}em(b4<{88|l-1=m` +z0cZY1?)yB2v(Ga)`#hIhpTCTL65oy>dYEV6y>jc5`F=R_gL2>J5S)FEz}e@R-1>Pm +z`Wc5m20kUXKABI!na{|5pEGdwISXf>b8_qRvFK+WJ_BEpTc6D5;mohfeV=P^_PGIP +zpPO>)^Ks~B3;rwclHB@aeizRCzTEeD0B4_vaQ1m5w>}?_eyZ>+ye_vsnQy|GKb8AF +zTX6Q-hO^JaccKNOhxPdc^wR@>BD_y-eKJ1)XMRZT`y7U|&rvx09G6?4PeMNv@LBk@ +z-1=lb4QGBv?)%Kb*=G*UKIi4u=abRT0{kiPWx4gq{0f};HM#F|9nL-raQ3++w?3bW +zev0rMd`E75GQS6B{y^^gEW_Dn1Yb`dNg}!}D_MllfIR^Xqco=LVd8Zo=7TQEq)c3;k@ve;vLj +zw?63yaMmfyeV?cB_aviYdbH%$&u?JebJVBzv^)PttN$R>Daq~gGyHk`J97J+488Yz +zojSJe0@m$=FXD4S19F=K^Fwgvhvn8Me_rS)>i;Izoj@J>B=S<~QNYZ^`|9O7fpLk8*z=+j2XPi|F%QZvD`c-;W@A +z*t(o&9{$Uhu8Umv$4-nV&pR34Pd3JjF}^Ri{-2Bf59HQA{Y>ur&;0P>eir4H=lR`$ +zXK=h*a_i@}(9gEq`k|Llhx4q$S-%lezZp~i1a(-y=SLSG?||I;|84X?B)9(Q^KzR{ +z3v*aNoh8&+LLK@#>U=!e>COJEpw920&Jmo~#WCtLUxzc_kX!$}&-DDb(}TZ`l5)Rq +zGjf~T@1oBcxy_B9lly(R98(=3{(?osdPvOkB +z@5TLO4xUH-RXBgH^19rv7p_~B+x0Sz*C*R@+i&y|>htF+@4&x{KFg^8eAKU?KK&SV +z`17|LazD?e+#lEY6`eWzc}~GO&orF#T!3?)OLD*Nn%vKGUGC?(f%=?h0nT}Dp?)6w +zc^mcVyQsr?R^Xq){u#evnA=Nn9gu0O=OvvNBw`aJ4<8ud5eeEqNs=ekXJ9d%MY +zq0i62*X7pdAED0;`19afa_gV@Z8-BKxxe0bQGW&X_u#B^fcnfI!kMqg{kkXcm*IT% +zUK!>?--dq{b1TF7bFgc0*6F`dr@qbk`8eJIIQt)x+nkvnfipiU_s2US_xFKGxxXF@ +zsKfhe5zhO-4xIOaDxCL$W4T|q9g{zg$@g9g^W^=uPi}Lg_seZQyl)J^dEXdE{TJYT +zO`<+Mg*p$#KFOdC@7r0_q0gZX?>|fM2I{ZK{rO#$`#IN9hv)YM&hvW)=lLB-hUJg%b-eG_$f +zeoOE#;Qa2RK7YT=0qWB$$p10+?Gf_ys@z`}$8gTACb#{@pZ8vu+j*y-%I!R^qMx?h +z&Lcf}jxzALwR(i1lc^Z60#_rgcvDfqjv?pll=#dz;c!@BQ4opJcxuz<0HMHA0F?h+}9~0&*$sun|1136V3Tgu&+|^7r|%bDVLvxGoO?DeKm*r +zYp6dDXPqU~XFd;SensxrT}Ayr#ky;7*4aRP<~QNYZ^`|-4fs>BAJR7u=aIiRx$hRi +zzli)eoOQBtJCD!6*G;o<{{G@Qxt&Mm7vRh<%KdRIq5eG9U52wx9`%`Dg)_e<_v@~s +z{xh-e2Ap*^QJ?uDocV3JU-tmc=YFUI{UBTqS>MIC;hWgh+w)L)TXpZxyRs@(ddAIPnrm!O}r-1?zcB?(Z9A)aU)@5Y9SB +zsL%W{ocWsEuUkib-ftUl)@hhSBVVY$_z=j1m3U&9<$;E#vz!5;@dliRv4 +zL;roZ?et^o(g)a))Z{3htX3jZMbslz`6Z^-?+C&+&k`BV6fvFBGnukRL&wJ}S3U_%-ofx*F}d9b_*e*FB`<-Y&2+|J`C +zv2HCU-#2ve@lL@xw`sXwH-|juHW!o6BhUIPG5HO-?H_)>qae5aL*GPwe!pW2&g-j) +z`diqa+wceB`r4J-y3FsxnLm*G>#L0V-@9Q{Opil2>r_#n`5K)0y4vg%GXH)Ly)^pde +zKRJg1__y)C55rk!9R7_<-Kj-?9~I8}d3Z18unIpzKRfV0!+EU1FQHCyI2&g*?bZu4h;3eNnr-0%Ms>i<2~O~Y9yi~7vx;LOj-{kn^&|7xte1ZSNU +z)MtJT&iuOEuUmt^1m~*-=Xr0#dEQ5^y7)X!$?ZJ;1CDDN&ewq%xt&MmvvB5T<^H%9 +z;kUqkTY|q0`#%rwLw*DPZsa%Nw?uyEZeb4G=i_pl!#3tH0q1c|%WV$Kr{TNCFs +zXMR`i*KNajz4YBZ><50ICj2pUe--ZQqtK +z&uO{sPkI)0`1RK!{0+Fz&PnL>UJ`RSPaPK?jqGxSqJokck3HuEzfe7K&>vI23 +z!ml?sxy|8qm_tr(bD+V!@mbe(t_u&OGlYa+~MtG0#)@wfH);CAT><--a`PF8BB6@%x2-xPKPq +z*3Vm_|3vQwU-#$gPxy75SeIKr%$HD~^VxHC`c%K{>U6z=I^2g2-A?>6et6Za4E`7!qAklgC*;Cv0sZ4UHN)Zym?r{HIoLPHC1en0L+ZtMOt);*Qm +zy7V*D;q&ImcsQ<4VBImf)qex(kISt-eG+w8e+JI`RSxyvi~T&0`t&8#c_`+;0e=Jf +zFT#HSFT>vnugL9q--zQqlH2jptEj{C(um2QApaSx+k&%B@&VzzFy9O3`(tBr>wg#h +zPspu*`XuUHZy&;0KP9*O>LtuSEw}q2J%c*8#p{Y?I9~_m<<|e3(EqC3`lqj>4!@66 +zK%IXyti-I(&a41HU8YGmrXw9kqb^^d;2c9P)CT!#?J)Dz`b%*HDM&aUIS% +z6ySG2|Htr~Vc)jk{Cr?yB3wuGz8If|^ZSn(xgGCYalA8fJ6?Jgb$GnvG@c +z$b-Y2`SsTfoUhMwa$EQ9n9qXT)}=3_4qxxB!fQCc1^D&mBe!)AuzY~3~!}+hP`rLrCpDnrd&-^x=`I6lCzlZvq!#^p!ACudh--|hn!+Bhja+?G5 +z({ScfazBSO>hnBiP=`K)Iy}EwIL~hZ^(#28O*s49mfLYLzXNA}SMHB%5B1-Nb@$<{ +zQ$~H}D{$tIc1cB9>ZCuj{3|u;mn`N{ko^9{{gJqg0oH=^_fphclM{vpZOlS +zUpFbYeS3s;d*Q4zfcnf2!I>YH`*lZA|ASa}49+?esL%WqocU?FUv~-q9lY+%%WV!H +zLO(0;|AMc}{nz6ga+^Qv6yU70Ew?^jm5lz-;{bj`_#vFn*A=;cAE1Rik9YLya3ACI +zU^>QE;Jdi*ZNT3IFT!t!{&(TGhnL}ZfLG;qUaFY?F`R#|tu9Zwd;`vWQ*QI;`}yba +z`{H>v@$k;vte(Y~Qt6#!=#^HSbY64!w9H!*9?uRjlX}PUSPoWO) +z^J)0??(^`QV%=T2?Q{P9f<5HeFYD&*S@&IppaJayyTGn9mBl0N;e)0$!5a9I{tLf9P>2w?63=)cIS~sl!>n +z1?T{zCaswc-{ve(W!5BxUVK+d`fP8{tk|JT5f&P +z)2PFJIDZ7>6(sJ8Z^o-oj3-AADaDHB8{*mGOI!65kcm{tjU|DYKGQR?6epPP$@O{5E)c+XP +zU5B$y0ri>Rf-_%~`*pWb|KnJ`90HL+_9A;TT`|rBLTLP=6Wz +z5AgbQeNF9)oh*Z}f4w)fvZqctURbq=tPs +z3I7WAPg-vKg!vgb^Rsf_|Hxy)zI_4upN22sy34?MJx)C~)cGpv9Kv~>_RoYoua`Bs +z&4K%W9nSqN9@;XTB`=>mI>5pSs-N#~N~fA3KrT +z+&+o@b1Jv_&|7lrhxhr7$A$C4ekyXS&+GIE&g-Qnw{@9sz?pB#{d`VPpV#RroORl$ +z&wS!nI>%-GFyABh>#oUd{(K#{F1Pv9Pf&+H=d%Up>!@=$f6nL7@97Pp*`p^?P>)PBtjk%4>ZEo}lxy_AVzfYnLzwVnt +z9eP@B{j;AOoXy!28<$i8?)c+jnZ=gQCfciX-*(Y`S^!?AtZO#qUUy@t@^kuo9b3Uei +zYBtP=b56^xK0Pb<^U1+^-OZss=e&UW^gQZt{;P1-Pd>TRzxBiCqd7QVKeXgF&(C9? +zXYgzBI_g|*b6~#bDV=rAnNP~CAAWr|O~<}X%k4gM^`+N_GH^bREXi$OeF6Jw8U7>es};HJALiHK%&*J+zS=Rl-qve>!@ke;pd9ea_fH|{m;m)PkI)0IOkb7uireJ +zb1uL+=Pmf_G3PzG_4y_Axew>u4&~NA^G9&zt8zc*W4WJmP44I1KpoEcMDFL@lKVNI +zp$_NVhI7sGx-}`cKAG=>Gv6=w^Bh3^XX1U5 +zK{)FSqdxPaaOTJ4e%*1@=g;|^fV0jd>N7tLXFetO>!wlPUMEj<#+%5X4t*JQegWre +zd@h_{zCS-HxAS-{u8V28oiBO{b@=*l26awQXBKtnt1)#p;rxEbF6w_1&r^HwZ^6rQ +z>!0}wocSZUpMO(s*Dt^BIFZ}+OYeI|m~;D5^e^@3hi}6N;rD?L$$kAvxqqE7g*;!6 +zrBVOZsGp6==aGL#vfF+1bGMM^@fMN)ChG6NFJm9>%dd$_e;NDaKyK%YUPc}6w$CYa9-oS(z5z;BFv4bJ)l&kXB61^E=5 +z_vdx^zaf7JXFoN$&HpQye;v-xfuG1zF5iMPel9F*`7Jo}MY&&h8}<2o +zSAw(7F6uMC4`=>B?$-2aos-*nVSWM5{G#0VnMZw|-xWCP +ztfD^i>u}~bht_=!da(?`plQ$%HUq)aoN5)#r>pTZu^HmAh)^kelm(W +zUqhWS)S*wr)R~t1xuxWOZu6+a<6V~9aeW>AtjO)S=&Pv1<2r;7V{Q#N@6V_3M<74A +z5cba_;gfKF&Mgh+=eTC!e7!dZ|0?!v9ez`I1D=G}e>3cdcXj?TnpE_jq}=94Z^~^y +zy!MhMJC9SjoyT9o@wSlXx@U4bzs!$3JIsx99+lhqwbw1($GF`3q-Riv&v$t^pZ8Z$ +zpP#2%M}2w$`Nv(+?I!x!U#Q=UIq#wl^M}Z@p9cKqsB;QWW6r(L33KEA>682O*pECv +z?>7eLew&K%O*s3n%KdeHEce&-soc)*H*o#7w@O2&woCW+i~%I^{U*Ci+&=vKEH)NPvzDpy)C!>z~6hjy>xM( +zM=^d5=RCK6FVx}d*an=(TU-u#et%(G?vHm5dH#H!Cj7&fqJz_;=l_KI{CV2_aP~6+ +z=lv}$w>ke0=A3~)4?ZKe`7=KYXFeyl^TO{d<$k}@zpcy9!_2|?I(A-e>oUIxXMRcU +z*IhyVGaT0{oc(X0KJ%M!=C|a2-6HCL8|!YvS!WmZncs&qe<1hkmQnvZSoaXlI#twX +zz6NK$F8AxU;M{Nhe-O?)KNm3|xARLMlv{n?=ZE0D&llj2!F_dKZu{-Kn8N{_$8{*T +zewaUkGhdbaIh>+Cua_2_bj|Z)-^b-23n>+GOD^LudS_vL=w1Jvi&%Vjw0R8XJ!DxCRaxnH-2`fcpDI-KY6 +z1ofG3!I?jk`*qWQ81}&J4N^Aphj!1FrC +zW&N}MklgyGuOk0F?1we@_u=cP!+ZhG{HEORhh6yN(0@(d?Z11x4b->(yWT_{&Y@=| +z%;6PRME?gp`sFqUdgA%l&-c|j|A(Z!oA3I7++H{G`_6-MdmTj|M*SaPo+GGFAC=qO +z`1*DX&gYkL)IUf43HT4;Q*t{l=2LLy({g_vbMU9)JZ{7J^L6*&Pe=Y(Zs(ov8`R|1 +zCw=4v;reC$QMuK5HO~8l-0ILLQHTA^!1=m&4nBwe^YCZD*Wk~)6fLet1wH|V +zXWE3be(xWLefuMv-#$1$Pce)2`( +zxL9Wi&N_KG>uke$UGKs9b@#s9@AIZfBQJb +z`(Ac&{b@Ms&&zE-d|q3C^LcGqZu4P&1B=kMJ+lKb;jg>(Kjxj$bGIP*=p +z@27?Od|%=W&N}C)&wS6Hb>?sVFrSqBb$jJ@ynKJ456(LMsL%W$ocSTSUw0Vw`F_X< +zoOQ-fpZN(m^OJJF?hgFvm!gB#qYmeNX?&wIPyakPA@|RNQ*xW<4RN2GmfLxur{vZr +zKlhb}^LcO^&ihgY&ij82&g-u4&%<>}-+(_9_x~Na9aj&IYZrbKyk0$!+wn4g2xq<` +z_vh;f^|{ZhaGv)X>NDSfGvAc^bx%;A`|T9YI%lZQ{5hQY#9xH@^L@@9xxXHhaMtOS +z+njkl_QRPUko)6Zg!B1p1J38oExBD6{5(uiZr269f;#;9s5N*V`>hG*^K2`|Ctn`s +z$?GBwXa8CF8*v|4hI0-@IDa1IE}VUq;jD8c_xF>k+}}@Xa@!AA;<{_d?Yz^Qa(_Qb +z7A~GoKl~Y(!vy?U@F_U&lNmVkvvAI55zhIn$o+g)<$gZva+}YMFrR|l=0o3<`}u6a +zdA}{8KHo>$L4Eom@^8Y|9Y@I1kLA|SYm(6)der1L2Y!85m)jiZ$-fNe_YZL$^~!BN +zmoT3`I6oggAh)?OKLlrfSnls9DL9{xGVs5_zS@#opPXkA`RC!dwvkWbxJvLF!}sNO +zT&#ZpXPq*fbt-Z@UcP>=$M`v%{SW+AIA7PhU%^>_F2?I{zMt8@8S3-8JC@s=Z-V*M +z;5UUgm-%ft^Ch|OX9x9fj&*n8th0~$ +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 +zcolUf%?`rKQ9N!e;o54 +z8xD0i=N!0_ZBRKCrH8@`{ox=YT{U`1jj*Iu1J~-buNW(vfI`eSWS%!ZU`BgaYSL<-T{x87! +zI&BNi``h_wI4;)dxmR%3>4me-&b>pP`{ejO!MU$?#xC~4eJ}R>{erXpW{mI0crC`; +zF+O?!i`Sir@r4*)jq%iYsQ+o4_Z*zB6XxN!z38!?`oyf~ke+kAN6 +zTa3w%|9qGa??01p-hZZJd>791JN(d#`<#?ppPXANCclY1pI;8(bzHxV7;neaADaqu +zI7XcmoX-nsxj$da$n*JP1b_Eo|OCfuf=#h#`_)->fa0N4#@4k#J^WED7SU#Q}Syf +zzY6bDP0Q`;dU{5FIdXn~A@Pf$AI^VA?vHosk)6Evl^EZZ+qyj7eYrp01JvR1HstfM;C`EjKMl{Pn{eiL;QadT9R3#6pMG3e_YT-sW4{u75Bb95FZO-8?Gt`~q%61n +zKtF#%sKa$9XM+!-pWKs!GhcpcaDGm&34c5KKY{aefXQ5_!*#cw7M$yD{c3RL>vO@G +z-~YAX?57N8{}njMJdbN}B{=(BlKVcF<-X5N)M20d +z@Hb;VM{s`sZtnS=etiA$7lb}}yi;=P^J-j2({igrFURB$WAatx`M%#V^7NMca~477l34BZX?}NjQf~J*=KJ8x +z_sgwMKHm+~F`uy*UxD*^@Ep$Puih7S`nPrI{c^vrX5@CfBRJkHoX0gMw>dDs0B3$t +z?&nZK{d-{D9XRXkqdxOxIP-^czit!G`@{5$!rXX&SXvAI4qU&haDHEY9nSm7hTPvz +z3UYs5_E3lSlkq?8^y9Dh3Aw-CQ^@l=N+VC7liS>Q{mvuL>#L0VS7SftUL5Ae`_-J> +z_gQ{P$n*1W6*%i0$$g!g+}}^?$n$v5P@l)!MxMtzu^#&5{Uil{4)#e}?$1|7?)zUv +z9bUg>IPU|KFAe=LzX9hyFTE_}xzGFmJUI95fZXrfLAmwM`Anh?_w6j4&x4C_J`c8H +z>i7Rer%yl6LAjsjmi%(mC-={GOuql+7uO$B?eBf_Fp7-q$IPcqIaPI$cx!?a2a(}#8)ZzX=jLDy%{?)jDo+3}*`rB|^+|Nb1 +z--o@g2>EAYJ}J2!7xzh8ZguE$sB%uoJZsKb4`{mS6nw`;Eo{#DGs0RK9?S`2ya+XkHb_5{v-dn)() +zwk7xbw(sx5y4<%ra;tMS&ik(1@3+jWLmlqV8M)8z%6Bbn5$kG9>r=c0ztR +z>Yw{$5_#^EJo4PPYjEz{4Y}`s8+q=ZUF5l+_vF6+Bh+F4Rpi-!c00_U`}r8o`@kuj +zeU7~*)Zy!yDfu6Yo*Qt^vj}H?;w_;*=Un}_;GFZZ+|Rit_j7Ke4(FWP5A`|cCY*CV +zg>%liw}v{L^8%c6uERO!{kMfWoO9ys!8x}Tu4daL#$*-^03`^AenMZo)a|7Myd=l|y~bdGcMsIpzJokZ6pL3p<`#CSj{hZfPhjTuIbIwagVO`ES59gdu;hb|D&N&b6$sYZY4P9ybotS^IxGp=X~FJG(w(pPQp3oWjN=&3g?{9;GA>y^I=`idEg7dIk#~*=R6H( +zz7FS{7rq$kbIyx$Kj$U6pK}3qIOlWtbMX3kaIrm>1@|<%X&bh6^IsY1* +z^WQoN^*Ohl7_Y)P|Gh7VI-GOstHC+vGr6C0TkhvPa2o1x&MR=vx#w#k&pG$PIp<9{ +z=bZR@sKYrY;hgg5oO7ONg*u#b>6;z*^W2g9c^=6xM_*rao^?3S +z*Z8->y8OPw9-Q;+Jqvlxa{$h{rQkf?5}fnjgL9s}-wx|?{$t+>&bdvrJMQN;Dfe@m +zm0xyqTYz(Jhj7j<^}Wy!=eGU*;GEkooO5fyIk%}FggTsC8qT?G!#TIgd8os=^(8t# +zJnM2a2Oe*~+|P4B?&mpyI^2g9IOjHdgRm~=whrff3UJP|1YgAcxeezW=C26ra&D_| +z&i??;`S;#1)Zu+;5YGBXaL)huMxhSpUz7X!*X4fx=cvQ^uU!iDIsd_AaLzvs=lo~j +zoc}zW^WTSa{v$UI>vBHRaLzvu=lqZ0oPQn8`s+6d>vI0Ry}|kWI~Hyh{OQMvMX1AmHu^elbza@Ml&>qbCAT{CZMj|7?0+B5 +z{>w3SD#-Kq4sYHv^vU`=aMqu>Rmii>#I3_|-4mbNnS}ogJSDf|Wj+IEenxI{;QRk` +zaQ43?_j4|xKIgm>Q|B-ye}p{e(17#z@Se)8AO7Cz7M#DQ_*`!DVZNuoGiP(=lX5?w +zUb(G1iuw1!S*IWMnID8RKP30-4x>KjJc>H>apdoXJ}2N@cM^4&pN2D^lKVc>aQ=Rr +z8M)2v-smR_XZ@Vq&I|MNaOM}}zMmD;AIH!AUPT@H8tOba87;2II-Eb3X#>vV-IUw$ +z-Ur9K1!w;yxg9U_yKv_B+fHPl~`{Sy@pN7{VBR?IU +zPkFpEF+LyT`551b@hUuVljz{|IF{S%)$d*EYVqDO-aP~7UxBi)*gfl-S_xFwFCQnCB>*^(W-k5A#!S=BMSp +zpA_ofAM2*!tTTi9%+JD^&&mC|bErR#b?4!%vxxf4FT|FrQgC>(9%rALbX~%rD7(KUFyAGj+#s{qpzc +zPQ%~Vi9{VF5^1^h!~6`K`K;XcGmHBCeZe_6>&&A*^NVoim*jrk66*8!_U^!0XBYLE +z--k1QAouI`-6_oZLD+}=a+@c8KyG#T_nHUce7>6>3iT&Ye*w?$bQS@yD0bXZ|}>k +zeh*$hAIR;v`1?M}@UP%LQ`Tanwk +z^dr>gy2q%)_v>n?L$9L_-^Xjf`8uJA`fdEY@e}y-;Ae8{pZRk*^ND+eeZu$KQ}87A +z?W)}G+cml04~M98FPxVn)VUh_u!=hLn%vIUUi6>tqb|4OrMKjEAGk64KSzCDUsLxC +zb6}s-a$EN;-9@ASPRngwdgdqcQ`h~!=6@pJ@ddffllya5?)UA1+>VR;{4ge8lUx7S +z+lO-NpWZ-y?$0Ki`|||8it~Fa_xqv$XF7AX4DI8ZzZpTGGll$X3m-~4pMmux%^GwQZ +z-Cw}Ey>eTZ-Y56#PNNR5yEN+1v#9eq?329Q`sek&BDenO8*=Oa#hpWp{wa|t$gO|+ +z;JrE_%g-V|EVn#;L~h4BfIg?;e4RD}=kw#dyxZq)RL>p@@@}79Uqb#e&dV}9i}xQ^ +zP>1<7IP>drJ1*YmH&LJWu_Efww^8S&xUV+gz3{<%cZP23(ud*ve8M99W~j3&w|#Qe +zrRWbm*5tNN=q1#-A?noO{QO2Mrv4f7{G3}`?$_+@JSBxnFk(&N?GSy3bEpIC@zA(a293Mi0v$V*aV? +zw3B}f@?H1&4DydfzUw}pMScePuKRor`NtvOb)TO{{#TIiy3a4h2 +z^W~U)*L}Vclkd9ES7Y*B_xT#~PsI7{y3aR|e-iRt_xTg#xqrIu^R1YC*L}Vnlkd9E +zC-l5y_aFAtb)Qehpnk) +z{4DlQ*L^;PJkM9xeLfSD@4C-tk$*D!>AKJ7kY_(#_xX9`dB5$t&o3g+`d#<=<(Pce +zeSQUb_S1ErUqk*Wm`~R&|2ufT*oet@-RC!B@?H1&Vobj4K3|H-circAk$)i?v +zqkh+YKB2D{?Ee3&$amfHzmNT#jLCQ1=lf#vUHAEcn0(iLekdm2b)O$Weh$amb)O$Y +z{u#)3-RCD_@?H1&shE7%eLfYF@4C-tV)9-0`D{$S>pq`D{?{;{uKWCaOup+rzli)Z +zQNQaxpN#gaJuXN8Il$MyBiCv4HEZ>+@OYv-`b5^Y`KF$FlO)Kl2qh^G9+!E`Fb@D!2N- +zj&+aWtW%fUy39A>%%8~px~Fnmm)~b^p$`2Fb@=`FHk{vo@0DBq`{TaXFSq{bBXa9A +zcS-*v`Y$_A_OLp?f%#;v)6V-#^zOd$b#lsEodwjHLmm2p+}Bw`o!>;AWz?as#MD_s +zooA!YI_l61F?C9)^BmOKK^^*DOq~PNSwx*f)S*{Uhwpp$q7Kh*+<6~H9iI2@`Ss_0 +z2L157&&Jg0o?n07=TV2}eKDp^_xxHNp5N~MC*^!KrcU?#S{4dty4eKV#`Np5v` +ze*fQ`_vhlgmsQ{Tp;zSox~R&npWi~AW4YC#ckg4qP7`&08+A@mhu)G~9qz;KezSg- +zP-hTz=p(4}(4_uH^k1y=J27?W|C>7R#q$XJp~ux3QfvOacdw&V^zXSJx^*ni`eUkN +zdHT5A=E*sv#n@=cD#JuwFc+wuI~NE +z@_gO3tGw^?KyH2VbyOM7*E2_Q>!0~!IP*2R^~2X)b-As}*HH~P>zv4KUFKVG=FjAQ +z-L~A;#iO+Uw3u);s17@bgy5(PrBEI9WVDuPJLQG+$T$L?voWb +z_sKS#`=liI`(#h<_sKq-^FNeZ|J*0sKg?H^_vfp-ulzpg?kjWFX{e6hCns>`Pvw5y +z?!L16+z;J-W%cRZedYH_cVC(R|NEr#b;SQ|?|k6us_Xxc6CEikDJJSP%Bh$*fw7Gl +zDcfMOM8ypiYYGgm1HJr--6=Ct)TvmgRI^s!Ra8`zE2*d`*H^MtRFq^?l&dclDkc@? +zEHb|J`@HY@yg5$}=eT>PeINZEkDbTka_)Wde!pMu&!6)-pYyr*+{^ku)K8oa7}QTP +zoPS5x0X8kPFU&5>K9&C2g7aFQ<cG>b4(S8D)_LG)-`_+`?5})J$t94%JwDG;`8#^rbo|ieFe;4{Qk9YDR +z8%N5;<9ZsL^MRQF-DHddydOEua&P@CvRvw)^_Gq}oQE$4=kax@ew+q*wd#lG3-*%% +z+wRg{3GK`NlWMuQ|7gGR_8;w6qRalne#QP{(~o}M={k(h +zN%kL-CwaN$68~`6kK#PS?{VD+&hK#@vt070{RBAeCoLCUj(hrDbHXc-PkW*PW|Mlm +z72`k$IKQuWr{$6l?YqEf-)*@!pB}`&4Z6F*8K)odX+Ho?`@NQXb%(+EJ-7QTmwLFy +zJ~vMj#=seW(sHQ>+V2Oa{j}xYe9~|q8QW#2h?`C9uSI+9j#8(++E8!3;J1V8b-Lt9 +z`@Pm)IPC{5_vTp=aNJ41mrd*|k>|z*Q5@}8tRMXxqtr9|ZP?m->oWpQ`xeVrn>g&} +z?cn@=W4-4~ba@;N1{`<8IKF7F$FJnceDwJB<}+gKWE1{AGRmbb=o(WQMDoc2wYd+Vnaoc*8I +zFV*N*T}DqfsULDZE+qahlf=T=CKfn*skgt|HWgxj9xB>DkH+ybZSAF8v`;{Ppnam{ +z-g4Qmi;l*>1MwGGd&!4!G7z8kdc7n0(B9sLJ8yog*E@XBLE0w;oCozgQAM{Mx~bOQTi!Ipr+qp&br%QdW+48((9HyAoGiqreI7XN +z^DXy|4+V(-Zs-<*p9@}s__Qwrr+vBQUfqp|&vCmFoa1&F@o66cr+tg%Ufniu&f9l@ +zbNuhMT-rSu_0R`S-2uy`|I>aDoc2SOd-K%uop7#uFIr%L*(9H1kxx1}+dac_$%pn? +z;Iz-Re6_LXIFM(#=pF^#d~n7owp?^+UkXn9GRs$cboKre;cPF?-;O~(H8zg-IOV*K +z_MF!-pP+eNE8??#+rZhr9hQ6h!wzuT@3efiryjb%dA-mVzy~asdf@S5e=a-Pf2ccb +z?IlmzkAl;FA9UGIbUw4%#NoWR%eM4_SNBp1VtbGy|Q&h^7~ +z%f0z?oTvS+0Q;GM_ +zOZ!Z4+GklVy6peCh<`u&A;)3%D?Q$&ytFTdF6~PKbjzXp0CYEkGyht|r+pJR?IV_Z +z%iDtZozQIsXa0JMSe~zn}7~eRq>ikgRaGdO1V1U_#v)*)kkodIkw)Vnl-($JAo|A0-d&iAZw9A}v +z)pE&)<761zuRlvZwAX$soc3+d3H<`D?%R+H1e{+9%twQOd<}iR%E& +zGu7Hl{*t5OLEcezwulG4l)}S6(pG}rap0wBNeQ&>NMLz6Tx(*=q&v9})bXlJr(53wj +zaN6$-(CtEej+5QsjMIbowC@F{eV^st{?=~FDVy*k@jZ}f3!-=)&#+wThrd&k2~OQS +z%ccHlUjR<~Ld#bhd$vmf^5^)|WY0m~d9U6x>+M%P)?VT>PDYXeW)sfO8MfFu5q=rw +z`6J-0x0a(N%KZ9FO?El^f12gqJTokpdgkwrWrDN+=UOiHO#6Ir+80>vt>-Y}zYpj4 +zCh+%zM-ZR(t>Cn8v)rrOi}?IKpgwT+lL5r1{UA8)hb;H%4kNyfInq)i;EXed__Ut@ +zr~RbmUfn6g=eW8bamc3;hvV%GILF(BW26+$Jb~xgL~!5)oc8O$X@4g;?f(p2+TRvn +zzXzQ5w}LbNBjB`u7dY*YMSr9H6!N6~2E?KLUtph(dfp8C4DebU7g^xXBTgRpdc-LJ +z-;OxU^JlQ1lP7pO;@pHd%=1&=%(Dn_nCCCRndc~YF?7EUUJCv^csckBs2`R$6M3?{ +zw<8Yi9{{KQe#B3Q?u+1zb9sR7Ut!NUAA_z99~~b~K|dtF-Hu(t)K$ild%&5`o!~6j +z9pLE_%xn@zul3}0hWs&`@OxpO6{QZp3p@|}L6o-u`~%>{;2#991m6i>3;rSSMV42a +zJ*t29eq`Zxsu;B_guOk*MM*ihJ(WdC82q*Nx$N5PbBTX~eJ(p)XBK`Uc#nN9{3P%_ +z;3tD8*!2prKNVa*-zZ$mF8|Je{b{h*&k>3J>EQZ4i|};t8pL@6cnkO$;2q#+f_H(R +z1>OgKHn^^DOFr87_>p66f6LGv|+9X9>>)*Xt?a=Yba>&Jyr4 +z@bkfSo+EMe7?FSLI=1j^0d~{%XW=;t&3-rH=YkJ_F9RO|UjaS=uE(bQTi3BgcO~po +z4tHJ%zW{tO_?yA=!1KX%{Z`_<1-ugW7lP}$tJq%zuIo#}3&3?9N%$)8Uc_Gwz88EA +z_$YW0_$0W@DQ7o3->WuY-7GZU2L&$I#=2#IU#igTBjA^Tw}W2}uImhb@{G4LC~buJ{jdQOyo>wC(=>jl_Nf15*igF>^2qNG0Ax$`L}?lfo}uP1iuAbKO-S=-U+V1 +zEhW4aJc2my0&fSu6?_-?ZQ#A&ZQy&sZwJ@8y5w^Qc#55D3BMCO4}3d#3HV*$`dM*_ +zb2oSd_V_k!;Se>ZrVonuR!_kd@DcYqgw-v?d>em{5{_ygcOz&pYF +zz~2i#4E{dw8SwXm=N|36kaFo-v@OkAfE*92)+rj(6yTQK>-Vgo_@FDO=z{kM% +zfG4ClFQgv637!i6-{2YGkAmle4}gckzXjd_{up={__x9P!1sa=f`12mANY5{lV9t+ +zkn(;HJRN)xJQw`?;KkrS0N)7yL+~c>A@J?sKLXzg{$udn;E#h3fDeO@fd2$M{dnhv +z)Wc7~^T9{JOTm8zUIYGf@D}i2fOmlZ61*GySK$5NPlAtt?*pF#|225x3C;^C?{C1< +z!2bt46MPK30Q|S$W#GR9uLb`-cn|nE_#W`5z=y$~2A=_c20SIzc_HPU0ACFLEO;LH +zAHd7Np960Kp9Jp!|08%8_@BW0!2b+B3_b-u4*op&H27b@lTUPBNIkp&o({eryd3;R +z@OJROf)9ZI4SWiG8a(lJ&I`%s@8EghFM(Hr{{y@od2%ZnFp8*!j8t~V^ +zz7zZ?@GelqM^z)u0+34SX0ZgBk!p2QyjKMnRH +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 +z=auRkt#zoj;`-*Q`cT3WGn#I-pEGdY{XO` +z&C!?Nr&2%N2l;FBvi{|Ftkh5ULH;d1`OEK7sh{qH{M&r|<#(dgPxnFo?bbip?xp@u +zSs1(j4j=zh2dh?TYt9Sk~sVaeEgT1U|R3G532t`AOGAq{D-YS +z+i!Us{`-9V<@eS!Z`}vwKjGsqzrUt_x)1W-@8d7Oi>7|M5Ashq%n88q%kQwMpYDVF +zlYRWeNs7LH@-) +z{_^{H>Zki4|1ux{r{eIh^zomJ!$0ifFF)X=dFwtX{}vyA`Q115(|wS?eg_!)??rL= +z>vv?)zaS3(T|W7*jl*BRQ;PZ*$KkKv(M12^IQ;cHjOZ`F+pG1i`=I(C@+p659RB)U +zI@G@+4uAbF8~U%0!(YDxhW=N@;jiD3LVx)kQLQ)K2i0HFg8Ad`#yI>_ef+PD!#~}} +zUw+F)^VWS({+T}h6><3I`S@4G;a}+EzbOv?QXl`@BK?EoS{c6NkUvdrSWXN5$U%_1;wa%kP`(aija7 +z<45lerT@Y>{Pmtn`X3#Kzut>TfBF4f&0F_D`RhG=^nYg@^MAd^jsB0vG5^qe!00~` +zhrj+_BK?07hriy7ME~J9{PkWP`acnezuqfD|HX0Czurqi|6Akm*LyAK|ED3?J#$A6QL|D`_u>E<*oQysH3FlTGE{;Ap!_P=`EsPU=hiLe3%c0cuy +z6LIQXXCRdIgSVQ8sezV-ny;k3A?|uE@0RO=l{htW%ABxfcHKy=>k)`>#xV3hVl9zY5I-m=cs|*Ph0=>_C7ZK +zxAtH0k?j=gFLAh)eA?;JqlD(USN}xgC#=BZKW2a2Jj?pa@mFphs;|eNeD{%G{Vo2C +zqhIS0^t?a`eZ{n9a?rFW({KSNPF{PGn5 +zUVWKo`00ng?C2+&F_W8DU%p$yPru*lv;O54ey_gV%j~D$w8!dG+&uT{%RP|dZ_=2v +zwOIe1PMF#MslEcacQcy50=u8E`41oK0I9z!^H6{7KXUJ3G=J--yOaS(_&~>x+ym*S +z-~WuGq&lKs?V~UE0{Ye8BC9{33E923{(cbPzt8&XI;w{8`sW!S`Z;P~_r2dTfz9?` +z_OnQ1W!AkyeYqaWX{yA3Pn}7RW +zC;!VR27k@}?tuJ9t^Xo5v~j%o-){W<@}GLn$+R8yFQ)=;{zC!zPk+bB-#af;e@#n% +z|5=`U`%l7m9sdHGx9+_8FEsvs`M1bq*KEbsQR-iAX;yu${|l|YxBd&PzLSLw0)Nf_ +z)`0vAW6XbBK>hc8Dy(|Pp^rsmgwtB?L?tiHGZ?zH-HeZfuZPy6rF0r~H>{%v$N&%OEoHX#3Y +zn}4PCm-f5OJXBwgzmp7*T)g=g4?694uJzZQ`fL7IS%2^N5wZSl>S*`g{I4+n!o2lA +z;gkOz#!mG$|Be9t{Z>Co6AjS6CqTdWc}I!ozwJKya+(ndZ~14wZ%3{J=#K~JH@z@l +z|85_Bc~8h!UnVB99YFtVdrj}H|D7++*KarB9GZ}z^&htS-u{y?G#G++M#AN|fC{U67s|DFK-;hFjR@Ac9DLy-RCj{bp; +z-=_lfr~f%$|NTDt7ar|j|0Bb(m4Bu2_Zz>`4>KLhY;6Aree`b+(*H?p`mF)_#fQ(= +z|DcclqgLO0{Ej~1=*#*NH>XzJVWrSqp!xOR$WI-AI}M%<;XQsYGX8$`*K~xFf3F=V +zFDd{XtWZ&<$pdvzw7Av`k(UA +zzv4Kj{=MzjzR%JBtP0z`)}J=ZzpTG^{*n7@$3N3tA9C~N|B~_dYrlbHC;ui~fA*L_ +zs;}+$F|$A_xp?!h{GFp;KymnM{>#jVPvyBc|1RraqlPw)H~%c-@0WkpaZdh{vutww +zK4c!={2vR@PaJphA9HpRBD#6?zZsxEYW3OwKW`#<^;aG5U;goD9AW(&j+Kv=RiDc~ +z-}w8Le>%k}f1a&BDgVRf;nn|!)z6V&*jk=-^c!sZ>%Y`rn`Nt+;Q6)R#B+}Su&2U2 +zFB6)KzhC}Y$2yj&hw5wpdt<79|LdP}^ec@IH}%*2$E?4%|D`?e_%HS( +z?0K2+r1AI5zbDPfe;CKlS4<+RulYZCqJRD6zv$?XIJ?;*c=bDtzn^}~sgC|2+W%`l +z`X{{3Uq9vVj_~NLvh&2Nf2{HM(=Ry9(bsZH`+eO<|DFK-39Emg^Y*tU7 +z=#K~J_r2tlzh4{7DSou9_GxtYKLPsfKKkGE(LeVj|N0Lf?$mTS#msYW{hww0{p!Ep +zNB>bD{gwdzy;gs}J^nNeul|+*{RtoaZ~5py8lc~QRBYw{Mu2|W=}!M+`+wUk@0y3|8@K2- +z5}-eFoRj~Mv$NLo`_JP6`dw!@^+)|d6UD3lmXrPKuPfCNwqO4|tFQiAfA6>c-ug>8 +z(ea-#=T~l?;w0Q}{Dpb1f2T8?{HLvh)ZY)yL-n=(o(#x8;cUmz+#WM$Q-95W?J54p +zZ@TqA(D`GP@%PJr>O3d^DXT8||JXcKU-Rz?&@VjK$=^Hwx79IQrcVawk1cWZRY&xP +zee{Q|{^6c^LaEg+o>g+5X#R?S7@$9G^?R(L=s#f|>aTgd#(aQ8+QO^9)9R<2|8Y}) +zWr@b$ul~EvcgoN4W5hVAzv^EUpx+;({sjU0!#?^y_tAfMfc|KV`gaBBCuGep|EQ1t +zV*&cpG3tLaKtIbz|5rZx(*gQvnNCknH$L37{gk~BpkL{uzt1?SzqbF9MgILSFGl@y +zjK5$1>-5q8jgS7-0s7@uzgP=u_nN=r^#S?=R=>v@%JDa59_p{c8Ij`}MzJAN>g*{gCS0JayM(_0!UoID5@sX{G8b +zu=}*7PW@{+rTl*|5A|0b3D9r9)M@|H0vpio)L&_1fPR+MPq!y}(VsLA^;iAvR$tE( +z8h7+QNB?{UcCYgW-QQ>ZJ!T0D?|1yYT>X@P!uoqozX?g!zw2hTboQFR(vJj`zckmW +z|Jt>VrIcUhBI>W@mwde1;?Z-2GjZ(_N3*?P9#5HT39rAXc&5l=o=`mP_(SB) ++ ++// func runtime·RaceRead(addr uintptr) ++TEXT runtime·RaceRead(SB), NOSPLIT, $0-8 ++ // This needs to be a tail call, because raceread reads caller pc. ++ JMP runtime·raceread(SB) ++ ++// func runtime·racereadpc(void *addr, void *callpc, void *pc) ++TEXT runtime·racereadpc(SB), NOSPLIT, $0-24 ++ MOVV addr+0(FP), RARG1 ++ MOVV callpc+8(FP), RARG2 ++ MOVV pc+16(FP), RARG3 ++ // void __tsan_read_pc(ThreadState *thr, void *addr, void *callpc, void *pc); ++ MOVV $__tsan_read_pc(SB), RCALL ++ JMP racecalladdr<>(SB) ++ ++// func runtime·racewrite(addr uintptr) ++// Called from instrumented code. ++// Defined as ABIInternal so as to avoid introducing a wrapper, ++// which would make caller's PC ineffective. ++TEXT runtime·racewrite(SB), NOSPLIT, $0-8 ++ MOVV addr+0(FP), RARG1 ++ MOVV R1, RARG2 ++ // void __tsan_write(ThreadState *thr, void *addr, void *pc); ++ MOVV $__tsan_write(SB), RCALL ++ JMP racecalladdr<>(SB) ++ ++// func runtime·RaceWrite(addr uintptr) ++TEXT runtime·RaceWrite(SB), NOSPLIT, $0-8 ++ // This needs to be a tail call, because racewrite reads caller pc. ++ JMP runtime·racewrite(SB) ++ ++// func runtime·racewritepc(void *addr, void *callpc, void *pc) ++TEXT runtime·racewritepc(SB), NOSPLIT, $0-24 ++ MOVV addr+0(FP), RARG1 ++ MOVV callpc+8(FP), RARG2 ++ MOVV pc+16(FP), RARG3 ++ // void __tsan_write_pc(ThreadState *thr, void *addr, void *callpc, void *pc); ++ MOVV $__tsan_write_pc(SB), RCALL ++ JMP racecalladdr<>(SB) ++ ++// func runtime·racereadrange(addr, size uintptr) ++// Called from instrumented code. ++// Defined as ABIInternal so as to avoid introducing a wrapper, ++// which would make caller's PC ineffective. ++TEXT runtime·racereadrange(SB), NOSPLIT, $0-16 ++ MOVV addr+0(FP), RARG1 ++ MOVV size+8(FP), RARG2 ++ MOVV R1, RARG3 ++ // void __tsan_read_range(ThreadState *thr, void *addr, uintptr size, void *pc); ++ MOVV $__tsan_read_range(SB), RCALL ++ JMP racecalladdr<>(SB) ++ ++// func runtime·RaceReadRange(addr, size uintptr) ++TEXT runtime·RaceReadRange(SB), NOSPLIT, $0-16 ++ // This needs to be a tail call, because racereadrange reads caller pc. ++ JMP runtime·racereadrange(SB) ++ ++// func runtime·racereadrangepc1(void *addr, uintptr sz, void *pc) ++TEXT runtime·racereadrangepc1(SB), NOSPLIT, $0-24 ++ MOVV addr+0(FP), RARG1 ++ MOVV size+8(FP), RARG2 ++ MOVV pc+16(FP), RARG3 ++ ADDV $4, RARG3 // pc is function start, tsan wants return address. ++ // void __tsan_read_range(ThreadState *thr, void *addr, uintptr size, void *pc); ++ MOVV $__tsan_read_range(SB), RCALL ++ JMP racecalladdr<>(SB) ++ ++// func runtime·racewriterange(addr, size uintptr) ++// Called from instrumented code. ++// Defined as ABIInternal so as to avoid introducing a wrapper, ++// which would make caller's PC ineffective. ++TEXT runtime·racewriterange(SB), NOSPLIT, $0-16 ++ MOVV addr+0(FP), RARG1 ++ MOVV size+8(FP), RARG2 ++ MOVV R1, RARG3 ++ // void __tsan_write_range(ThreadState *thr, void *addr, uintptr size, void *pc); ++ MOVV $__tsan_write_range(SB), RCALL ++ JMP racecalladdr<>(SB) ++ ++// func runtime·RaceWriteRange(addr, size uintptr) ++TEXT runtime·RaceWriteRange(SB), NOSPLIT, $0-16 ++ // This needs to be a tail call, because racewriterange reads caller pc. ++ JMP runtime·racewriterange(SB) ++ ++// func runtime·racewriterangepc1(void *addr, uintptr sz, void *pc) ++TEXT runtime·racewriterangepc1(SB), NOSPLIT, $0-24 ++ MOVV addr+0(FP), RARG1 ++ MOVV size+8(FP), RARG2 ++ MOVV pc+16(FP), RARG3 ++ ADDV $4, RARG3 // pc is function start, tsan wants return address. ++ // void __tsan_write_range(ThreadState *thr, void *addr, uintptr size, void *pc); ++ MOVV $__tsan_write_range(SB), RCALL ++ JMP racecalladdr<>(SB) ++ ++// Call a __tsan function from Go code. ++// ++// RCALL = tsan function address ++// RARG0 = *ThreadState a.k.a. g_racectx from g ++// RARG1 = addr passed to __tsan function ++// ++// If addr (RARG1) is out of range, do nothing. Otherwise, setup goroutine ++// context and invoke racecall. Other arguments already set. ++TEXT racecalladdr<>(SB), NOSPLIT, $0-0 ++ // Check that addr is within [arenastart, arenaend) or within [racedatastart, racedataend). ++ MOVV runtime·racearenastart(SB), R12 ++ BLT RARG1, R12, data ++ MOVV runtime·racearenaend(SB), R12 ++ BLT RARG1, R12, call ++data: ++ MOVV runtime·racedatastart(SB), R12 ++ BLT RARG1, R12, ret ++ MOVV runtime·racedataend(SB), R12 ++ BGE RARG1, R12, ret ++call: ++ load_g ++ MOVV g_racectx(g), RARG0 ++ JMP racecall<>(SB) ++ret: ++ RET ++ ++// func runtime·racefuncenter(pc uintptr) ++// Called from instrumented code. ++TEXT runtime·racefuncenter(SB), NOSPLIT, $0-8 ++ MOVV callpc+0(FP), RCALL ++ JMP racefuncenter<>(SB) ++ ++// Common code for racefuncenter ++// RCALL = caller's return address ++TEXT racefuncenter<>(SB), NOSPLIT, $0-0 ++ load_g ++ MOVV g_racectx(g), RARG0 // goroutine racectx ++ MOVV RCALL, RARG1 ++ // void __tsan_func_enter(ThreadState *thr, void *pc); ++ MOVV $__tsan_func_enter(SB), RCALL ++ JAL racecall<>(SB) ++ RET ++ ++// func runtime·racefuncexit() ++// Called from instrumented code. ++TEXT runtime·racefuncexit(SB), NOSPLIT, $0-0 ++ load_g ++ MOVV g_racectx(g), RARG0 // race context ++ // void __tsan_func_exit(ThreadState *thr); ++ MOVV $__tsan_func_exit(SB), RCALL ++ JMP racecall<>(SB) ++ ++// Atomic operations for sync/atomic package. ++// R7 = addr of arguments passed to this function, it can ++// be fetched at 24(R3) in racecallatomic after two times JAL ++// RARG0, RARG1, RARG2 set in racecallatomic ++ ++// Load ++TEXT sync∕atomic·LoadInt32(SB), NOSPLIT, $0-12 ++ GO_ARGS ++ MOVV $__tsan_go_atomic32_load(SB), RCALL ++ JAL racecallatomic<>(SB) ++ RET ++ ++TEXT sync∕atomic·LoadInt64(SB), NOSPLIT, $0-16 ++ GO_ARGS ++ MOVV $__tsan_go_atomic64_load(SB), RCALL ++ JAL racecallatomic<>(SB) ++ RET ++ ++TEXT sync∕atomic·LoadUint32(SB), NOSPLIT, $0-12 ++ GO_ARGS ++ JMP sync∕atomic·LoadInt32(SB) ++ ++TEXT sync∕atomic·LoadUint64(SB), NOSPLIT, $0-16 ++ GO_ARGS ++ JMP sync∕atomic·LoadInt64(SB) ++ ++TEXT sync∕atomic·LoadUintptr(SB), NOSPLIT, $0-16 ++ GO_ARGS ++ JMP sync∕atomic·LoadInt64(SB) ++ ++TEXT sync∕atomic·LoadPointer(SB), NOSPLIT, $0-16 ++ GO_ARGS ++ JMP sync∕atomic·LoadInt64(SB) ++ ++// Store ++TEXT sync∕atomic·StoreInt32(SB), NOSPLIT, $0-12 ++ GO_ARGS ++ MOVV $__tsan_go_atomic32_store(SB), RCALL ++ JAL racecallatomic<>(SB) ++ RET ++ ++TEXT sync∕atomic·StoreInt64(SB), NOSPLIT, $0-16 ++ GO_ARGS ++ MOVV $__tsan_go_atomic64_store(SB), RCALL ++ JAL racecallatomic<>(SB) ++ RET ++ ++TEXT sync∕atomic·StoreUint32(SB), NOSPLIT, $0-12 ++ GO_ARGS ++ JMP sync∕atomic·StoreInt32(SB) ++ ++TEXT sync∕atomic·StoreUint64(SB), NOSPLIT, $0-16 ++ GO_ARGS ++ JMP sync∕atomic·StoreInt64(SB) ++ ++TEXT sync∕atomic·StoreUintptr(SB), NOSPLIT, $0-16 ++ GO_ARGS ++ JMP sync∕atomic·StoreInt64(SB) ++ ++// Swap ++TEXT sync∕atomic·SwapInt32(SB), NOSPLIT, $0-20 ++ GO_ARGS ++ MOVV $__tsan_go_atomic32_exchange(SB), RCALL ++ JAL racecallatomic<>(SB) ++ RET ++ ++TEXT sync∕atomic·SwapInt64(SB), NOSPLIT, $0-24 ++ GO_ARGS ++ MOVV $__tsan_go_atomic64_exchange(SB), RCALL ++ JAL racecallatomic<>(SB) ++ RET ++ ++TEXT sync∕atomic·SwapUint32(SB), NOSPLIT, $0-20 ++ GO_ARGS ++ JMP sync∕atomic·SwapInt32(SB) ++ ++TEXT sync∕atomic·SwapUint64(SB), NOSPLIT, $0-24 ++ GO_ARGS ++ JMP sync∕atomic·SwapInt64(SB) ++ ++TEXT sync∕atomic·SwapUintptr(SB), NOSPLIT, $0-24 ++ GO_ARGS ++ JMP sync∕atomic·SwapInt64(SB) ++ ++// Add ++TEXT sync∕atomic·AddInt32(SB), NOSPLIT, $0-20 ++ GO_ARGS ++ MOVV $__tsan_go_atomic32_fetch_add(SB), RCALL ++ JAL racecallatomic<>(SB) ++ MOVW add+8(FP), RARG0 // convert fetch_add to add_fetch ++ MOVW ret+16(FP), RARG1 ++ ADD RARG0, RARG1, RARG0 ++ MOVW RARG0, ret+16(FP) ++ RET ++ ++TEXT sync∕atomic·AddInt64(SB), NOSPLIT, $0-24 ++ GO_ARGS ++ MOVV $__tsan_go_atomic64_fetch_add(SB), RCALL ++ JAL racecallatomic<>(SB) ++ MOVV add+8(FP), RARG0 // convert fetch_add to add_fetch ++ MOVV ret+16(FP), RARG1 ++ ADDV RARG0, RARG1, RARG0 ++ MOVV RARG0, ret+16(FP) ++ RET ++ ++TEXT sync∕atomic·AddUint32(SB), NOSPLIT, $0-20 ++ GO_ARGS ++ JMP sync∕atomic·AddInt32(SB) ++ ++TEXT sync∕atomic·AddUint64(SB), NOSPLIT, $0-24 ++ GO_ARGS ++ JMP sync∕atomic·AddInt64(SB) ++ ++TEXT sync∕atomic·AddUintptr(SB), NOSPLIT, $0-24 ++ GO_ARGS ++ JMP sync∕atomic·AddInt64(SB) ++ ++// CompareAndSwap ++TEXT sync∕atomic·CompareAndSwapInt32(SB), NOSPLIT, $0-17 ++ GO_ARGS ++ MOVV $__tsan_go_atomic32_compare_exchange(SB), RCALL ++ JAL racecallatomic<>(SB) ++ RET ++ ++TEXT sync∕atomic·CompareAndSwapInt64(SB), NOSPLIT, $0-25 ++ GO_ARGS ++ MOVV $__tsan_go_atomic64_compare_exchange(SB), RCALL ++ JAL racecallatomic<>(SB) ++ RET ++ ++TEXT sync∕atomic·CompareAndSwapUint32(SB), NOSPLIT, $0-17 ++ GO_ARGS ++ JMP sync∕atomic·CompareAndSwapInt32(SB) ++ ++TEXT sync∕atomic·CompareAndSwapUint64(SB), NOSPLIT, $0-25 ++ GO_ARGS ++ JMP sync∕atomic·CompareAndSwapInt64(SB) ++ ++TEXT sync∕atomic·CompareAndSwapUintptr(SB), NOSPLIT, $0-25 ++ GO_ARGS ++ JMP sync∕atomic·CompareAndSwapInt64(SB) ++ ++// Generic atomic operation implementation. ++// RCALL = addr of target function ++TEXT racecallatomic<>(SB), NOSPLIT, $0 ++ // Set up these registers ++ // RARG0 = *ThreadState ++ // RARG1 = caller pc ++ // RARG2 = pc ++ // RARG3 = addr of incoming arg list ++ ++ // Trigger SIGSEGV early. ++ MOVV 24(R3), RARG3 // 1st arg is addr. after two times JAL, get it at 24(R3) ++ MOVB (RARG3), R12 // segv here if addr is bad ++ ++ // Check that addr is within [arenastart, arenaend) or within [racedatastart, racedataend). ++ MOVV runtime·racearenastart(SB), R12 ++ BLT RARG3, R12, racecallatomic_data ++ MOVV runtime·racearenaend(SB), R12 ++ BLT RARG3, R12, racecallatomic_ok ++ ++racecallatomic_data: ++ MOVV runtime·racedatastart(SB), R12 ++ BLT RARG3, R12, racecallatomic_ignore ++ MOVV runtime·racedataend(SB), R12 ++ BGE RARG3, R12, racecallatomic_ignore ++ ++racecallatomic_ok: ++ // Addr is within the good range, call the atomic function. ++ load_g ++ MOVV g_racectx(g), RARG0 // goroutine context ++ MOVV 8(R3), RARG1 // caller pc ++ MOVV RCALL, RARG2 // pc ++ ADDV $24, R3, RARG3 ++ JAL racecall<>(SB) // does not return ++ RET ++ ++racecallatomic_ignore: ++ // Addr is outside the good range. ++ // Call __tsan_go_ignore_sync_begin to ignore synchronization during the atomic op. ++ // An attempt to synchronize on the address would cause crash. ++ MOVV RCALL, R25 // remember the original function ++ MOVV $__tsan_go_ignore_sync_begin(SB), RCALL ++ load_g ++ MOVV g_racectx(g), RARG0 // goroutine context ++ JAL racecall<>(SB) ++ MOVV R25, RCALL // restore the original function ++ ++ // Call the atomic function. ++ // racecall will call LLVM race code which might clobber R22 (g) ++ load_g ++ MOVV g_racectx(g), RARG0 // goroutine context ++ MOVV 8(R3), RARG1 // caller pc ++ MOVV RCALL, RARG2 // pc ++ ADDV $24, R3, RARG3 // arguments ++ JAL racecall<>(SB) ++ ++ // Call __tsan_go_ignore_sync_end. ++ MOVV $__tsan_go_ignore_sync_end(SB), RCALL ++ MOVV g_racectx(g), RARG0 // goroutine context ++ JAL racecall<>(SB) ++ RET ++ ++// func runtime·racecall(void(*f)(...), ...) ++// Calls C function f from race runtime and passes up to 4 arguments to it. ++// The arguments are never heap-object-preserving pointers, so we pretend there are no arguments. ++TEXT runtime·racecall(SB), NOSPLIT, $0-0 ++ MOVV fn+0(FP), RCALL ++ MOVV arg0+8(FP), RARG0 ++ MOVV arg1+16(FP), RARG1 ++ MOVV arg2+24(FP), RARG2 ++ MOVV arg3+32(FP), RARG3 ++ JMP racecall<>(SB) ++ ++// Switches SP to g0 stack and calls (RCALL). Arguments already set. ++TEXT racecall<>(SB), NOSPLIT|NOFRAME, $0-0 ++ MOVV g_m(g), R12 ++ // Switch to g0 stack. ++ MOVV R3, R23 // callee-saved, preserved across the CALL ++ MOVV R1, R24 // callee-saved, preserved across the CALL ++ MOVV m_g0(R12), R13 ++ BEQ R13, g, call // already on g0 ++ MOVV (g_sched+gobuf_sp)(R13), R3 ++call: ++ JAL (RCALL) ++ MOVV R23, R3 ++ JAL (R24) ++ RET ++ ++// C->Go callback thunk that allows to call runtime·racesymbolize from C code. ++// Direct Go->C race call has only switched SP, finish g->g0 switch by setting correct g. ++// The overall effect of Go->C->Go call chain is similar to that of mcall. ++// RARG0 contains command code. RARG1 contains command-specific context. ++// See racecallback for command codes. ++TEXT runtime·racecallbackthunk(SB), NOSPLIT|NOFRAME, $0 ++ // Handle command raceGetProcCmd (0) here. ++ // First, code below assumes that we are on curg, while raceGetProcCmd ++ // can be executed on g0. Second, it is called frequently, so will ++ // benefit from this fast path. ++ BNE RARG0, R0, rest ++ MOVV g, R15 ++ load_g ++ MOVV g_m(g), RARG0 ++ MOVV m_p(RARG0), RARG0 ++ MOVV p_raceprocctx(RARG0), RARG0 ++ MOVV RARG0, (RARG1) ++ MOVV R15, g ++ JMP (R1) ++rest: ++ // Save callee-saved registers (Go code won't respect that). ++ // 8(R3) and 16(R3) are for args passed through racecallback ++ ADDV $-176, R3 ++ MOVV R1, 0(R3) ++ ++ SAVE_R22_TO_R31(8*3) ++ SAVE_F24_TO_F31(8*13) ++ // Set g = g0. ++ load_g ++ MOVV g_m(g), R15 ++ MOVV m_g0(R15), R14 ++ BEQ R14, g, noswitch // branch if already on g0 ++ MOVV R14, g ++ ++ MOVV RARG0, 8(R3) // func arg ++ MOVV RARG1, 16(R3) // func arg ++ JAL runtime·racecallback(SB) ++ ++ // All registers are smashed after Go code, reload. ++ MOVV g_m(g), R15 ++ MOVV m_curg(R15), g // g = m->curg ++ret: ++ // Restore callee-saved registers. ++ MOVV 0(R3), R1 ++ RESTORE_F24_TO_F31(8*13) ++ RESTORE_R22_TO_R31(8*3) ++ ADDV $176, R3 ++ JMP (R1) ++ ++noswitch: ++ // already on g0 ++ MOVV RARG0, 8(R3) // func arg ++ MOVV RARG1, 16(R3) // func arg ++ JAL runtime·racecallback(SB) ++ JMP ret ++ ++// tls_g, g value for each thread in TLS ++GLOBL runtime·tls_g+0(SB), TLSBSS+DUPOK, $8 +-- +2.20.1 + diff --git a/loongarch64/0048-runtime-Mark-race-functions-on-loong64-as-ABInternal.patch b/loongarch64/0048-runtime-Mark-race-functions-on-loong64-as-ABInternal.patch new file mode 100644 index 0000000000000000000000000000000000000000..a435f74ed94da09680239f334464ecfc2069ef95 --- /dev/null +++ b/loongarch64/0048-runtime-Mark-race-functions-on-loong64-as-ABInternal.patch @@ -0,0 +1,132 @@ +From 3fccec3fad2e0fc91cb5b250462a8358b41dfe4d Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Thu, 2 Nov 2023 20:57:03 +0800 +Subject: [PATCH 48/51] runtime: Mark race functions on loong64 as ABInternal + +This adds ABIInternal to the race function declarations. + +Signed-off-by: Guoqi Chen +Change-Id: I123de85437344138c1942f5c5490d0bf7e27565d +--- + src/runtime/race_loong64.s | 43 +++++++++++++++++++++++++++++++------- + 1 file changed, 36 insertions(+), 7 deletions(-) + +diff --git a/src/runtime/race_loong64.s b/src/runtime/race_loong64.s +index 5e7bd6d716..0512efc045 100644 +--- a/src/runtime/race_loong64.s ++++ b/src/runtime/race_loong64.s +@@ -39,8 +39,12 @@ + // Called from instrumented code. + // Defined as ABIInternal so as to avoid introducing a wrapper, + // which would make caller's PC ineffective. +-TEXT runtime·raceread(SB), NOSPLIT, $0-8 ++TEXT runtime·raceread(SB), NOSPLIT, $0-8 ++#ifdef GOEXPERIMENT_regabiargs ++ MOVV R4, RARG1 ++#else + MOVV addr+0(FP), RARG1 ++#endif + MOVV R1, RARG2 + // void __tsan_read(ThreadState *thr, void *addr, void *pc); + MOVV $__tsan_read(SB), RCALL +@@ -64,8 +68,12 @@ TEXT runtime·racereadpc(SB), NOSPLIT, $0-24 + // Called from instrumented code. + // Defined as ABIInternal so as to avoid introducing a wrapper, + // which would make caller's PC ineffective. +-TEXT runtime·racewrite(SB), NOSPLIT, $0-8 ++TEXT runtime·racewrite(SB), NOSPLIT, $0-8 ++#ifdef GOEXPERIMENT_regabiargs ++ MOVV R4, RARG1 ++#else + MOVV addr+0(FP), RARG1 ++#endif + MOVV R1, RARG2 + // void __tsan_write(ThreadState *thr, void *addr, void *pc); + MOVV $__tsan_write(SB), RCALL +@@ -89,9 +97,14 @@ TEXT runtime·racewritepc(SB), NOSPLIT, $0-24 + // Called from instrumented code. + // Defined as ABIInternal so as to avoid introducing a wrapper, + // which would make caller's PC ineffective. +-TEXT runtime·racereadrange(SB), NOSPLIT, $0-16 ++TEXT runtime·racereadrange(SB), NOSPLIT, $0-16 ++#ifdef GOEXPERIMENT_regabiargs ++ MOVV R5, RARG2 ++ MOVV R4, RARG1 ++#else + MOVV addr+0(FP), RARG1 + MOVV size+8(FP), RARG2 ++#endif + MOVV R1, RARG3 + // void __tsan_read_range(ThreadState *thr, void *addr, uintptr size, void *pc); + MOVV $__tsan_read_range(SB), RCALL +@@ -116,9 +129,14 @@ TEXT runtime·racereadrangepc1(SB), NOSPLIT, $0-24 + // Called from instrumented code. + // Defined as ABIInternal so as to avoid introducing a wrapper, + // which would make caller's PC ineffective. +-TEXT runtime·racewriterange(SB), NOSPLIT, $0-16 ++TEXT runtime·racewriterange(SB), NOSPLIT, $0-16 ++#ifdef GOEXPERIMENT_regabiargs ++ MOVV R5, RARG2 ++ MOVV R4, RARG1 ++#else + MOVV addr+0(FP), RARG1 + MOVV size+8(FP), RARG2 ++#endif + MOVV R1, RARG3 + // void __tsan_write_range(ThreadState *thr, void *addr, uintptr size, void *pc); + MOVV $__tsan_write_range(SB), RCALL +@@ -167,8 +185,12 @@ ret: + + // func runtime·racefuncenter(pc uintptr) + // Called from instrumented code. +-TEXT runtime·racefuncenter(SB), NOSPLIT, $0-8 ++TEXT runtime·racefuncenter(SB), NOSPLIT, $0-8 ++#ifdef GOEXPERIMENT_regabiargs ++ MOVV R4, RCALL ++#else + MOVV callpc+0(FP), RCALL ++#endif + JMP racefuncenter<>(SB) + + // Common code for racefuncenter +@@ -184,7 +206,7 @@ TEXT racefuncenter<>(SB), NOSPLIT, $0-0 + + // func runtime·racefuncexit() + // Called from instrumented code. +-TEXT runtime·racefuncexit(SB), NOSPLIT, $0-0 ++TEXT runtime·racefuncexit(SB), NOSPLIT, $0-0 + load_g + MOVV g_racectx(g), RARG0 // race context + // void __tsan_func_exit(ThreadState *thr); +@@ -454,10 +476,13 @@ rest: + BEQ R14, g, noswitch // branch if already on g0 + MOVV R14, g + ++#ifdef GOEXPERIMENT_regabiargs ++ JAL runtime·racecallback(SB) ++#else + MOVV RARG0, 8(R3) // func arg + MOVV RARG1, 16(R3) // func arg + JAL runtime·racecallback(SB) +- ++#endif + // All registers are smashed after Go code, reload. + MOVV g_m(g), R15 + MOVV m_curg(R15), g // g = m->curg +@@ -471,9 +496,13 @@ ret: + + noswitch: + // already on g0 ++#ifdef GOEXPERIMENT_regabiargs ++ JAL runtime·racecallback(SB) ++#else + MOVV RARG0, 8(R3) // func arg + MOVV RARG1, 16(R3) // func arg + JAL runtime·racecallback(SB) ++#endif + JMP ret + + // tls_g, g value for each thread in TLS +-- +2.20.1 + diff --git a/loongarch64/0049-runtime-delete-on-register-ABI-fallback-path-for-rac.patch b/loongarch64/0049-runtime-delete-on-register-ABI-fallback-path-for-rac.patch new file mode 100644 index 0000000000000000000000000000000000000000..d8ee8cb589be62af38f37c4979d17495cc4fe524 --- /dev/null +++ b/loongarch64/0049-runtime-delete-on-register-ABI-fallback-path-for-rac.patch @@ -0,0 +1,110 @@ +From 6826bf5b6823bd13a14fa8e573d65985f122bc22 Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Mon, 6 Nov 2023 17:13:43 +0800 +Subject: [PATCH 49/51] runtime: delete on-register ABI fallback path for race + of loong64 + +Change-Id: I0769bdd12c8c458870a4bc6bbf731de4c3bbd997 +--- + src/runtime/race_loong64.s | 34 ---------------------------------- + 1 file changed, 34 deletions(-) + +diff --git a/src/runtime/race_loong64.s b/src/runtime/race_loong64.s +index 0512efc045..04f264b21b 100644 +--- a/src/runtime/race_loong64.s ++++ b/src/runtime/race_loong64.s +@@ -40,11 +40,7 @@ + // Defined as ABIInternal so as to avoid introducing a wrapper, + // which would make caller's PC ineffective. + TEXT runtime·raceread(SB), NOSPLIT, $0-8 +-#ifdef GOEXPERIMENT_regabiargs + MOVV R4, RARG1 +-#else +- MOVV addr+0(FP), RARG1 +-#endif + MOVV R1, RARG2 + // void __tsan_read(ThreadState *thr, void *addr, void *pc); + MOVV $__tsan_read(SB), RCALL +@@ -69,11 +65,7 @@ TEXT runtime·racereadpc(SB), NOSPLIT, $0-24 + // Defined as ABIInternal so as to avoid introducing a wrapper, + // which would make caller's PC ineffective. + TEXT runtime·racewrite(SB), NOSPLIT, $0-8 +-#ifdef GOEXPERIMENT_regabiargs + MOVV R4, RARG1 +-#else +- MOVV addr+0(FP), RARG1 +-#endif + MOVV R1, RARG2 + // void __tsan_write(ThreadState *thr, void *addr, void *pc); + MOVV $__tsan_write(SB), RCALL +@@ -98,13 +90,8 @@ TEXT runtime·racewritepc(SB), NOSPLIT, $0-24 + // Defined as ABIInternal so as to avoid introducing a wrapper, + // which would make caller's PC ineffective. + TEXT runtime·racereadrange(SB), NOSPLIT, $0-16 +-#ifdef GOEXPERIMENT_regabiargs + MOVV R5, RARG2 + MOVV R4, RARG1 +-#else +- MOVV addr+0(FP), RARG1 +- MOVV size+8(FP), RARG2 +-#endif + MOVV R1, RARG3 + // void __tsan_read_range(ThreadState *thr, void *addr, uintptr size, void *pc); + MOVV $__tsan_read_range(SB), RCALL +@@ -130,13 +117,8 @@ TEXT runtime·racereadrangepc1(SB), NOSPLIT, $0-24 + // Defined as ABIInternal so as to avoid introducing a wrapper, + // which would make caller's PC ineffective. + TEXT runtime·racewriterange(SB), NOSPLIT, $0-16 +-#ifdef GOEXPERIMENT_regabiargs + MOVV R5, RARG2 + MOVV R4, RARG1 +-#else +- MOVV addr+0(FP), RARG1 +- MOVV size+8(FP), RARG2 +-#endif + MOVV R1, RARG3 + // void __tsan_write_range(ThreadState *thr, void *addr, uintptr size, void *pc); + MOVV $__tsan_write_range(SB), RCALL +@@ -186,11 +168,7 @@ ret: + // func runtime·racefuncenter(pc uintptr) + // Called from instrumented code. + TEXT runtime·racefuncenter(SB), NOSPLIT, $0-8 +-#ifdef GOEXPERIMENT_regabiargs + MOVV R4, RCALL +-#else +- MOVV callpc+0(FP), RCALL +-#endif + JMP racefuncenter<>(SB) + + // Common code for racefuncenter +@@ -476,13 +454,7 @@ rest: + BEQ R14, g, noswitch // branch if already on g0 + MOVV R14, g + +-#ifdef GOEXPERIMENT_regabiargs + JAL runtime·racecallback(SB) +-#else +- MOVV RARG0, 8(R3) // func arg +- MOVV RARG1, 16(R3) // func arg +- JAL runtime·racecallback(SB) +-#endif + // All registers are smashed after Go code, reload. + MOVV g_m(g), R15 + MOVV m_curg(R15), g // g = m->curg +@@ -496,13 +468,7 @@ ret: + + noswitch: + // already on g0 +-#ifdef GOEXPERIMENT_regabiargs + JAL runtime·racecallback(SB) +-#else +- MOVV RARG0, 8(R3) // func arg +- MOVV RARG1, 16(R3) // func arg +- JAL runtime·racecallback(SB) +-#endif + JMP ret + + // tls_g, g value for each thread in TLS +-- +2.20.1 + diff --git a/loongarch64/0050-cmd-dist-update-isUnsupportedVMASize-test-skip.patch b/loongarch64/0050-cmd-dist-update-isUnsupportedVMASize-test-skip.patch new file mode 100644 index 0000000000000000000000000000000000000000..06b44efbcde43012dd09e63014705c3cb9f0fc4d --- /dev/null +++ b/loongarch64/0050-cmd-dist-update-isUnsupportedVMASize-test-skip.patch @@ -0,0 +1,35 @@ +From f3f6810cbfa56af01f213efa70a04e2f37344318 Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Mon, 11 Dec 2023 15:17:30 +0800 +Subject: [PATCH 50/51] cmd/dist: update isUnsupportedVMASize test skip + +Change-Id: Iba08f2c0bcc09fca34079e7f4c183d97b3f21ca3 +--- + src/cmd/dist/test.go | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/cmd/dist/test.go b/src/cmd/dist/test.go +index 8a1568c068..3822c5f949 100644 +--- a/src/cmd/dist/test.go ++++ b/src/cmd/dist/test.go +@@ -1526,7 +1526,7 @@ func (t *tester) makeGOROOTUnwritable() (undo func()) { + // internal/platform.RaceDetectorSupported, which can't be used here + // because cmd/dist can not import internal packages during bootstrap. + // The race detector only supports 48-bit VMA on arm64. But we don't have +-// a good solution to check VMA size(See https://golang.org/issue/29948) ++// a good solution to check VMA size(See https://go.dev/issue/29948) + // raceDetectorSupported will always return true for arm64. But race + // detector tests may abort on non 48-bit VMA configuration, the tests + // will be marked as "skipped" in this case. +@@ -1638,7 +1638,7 @@ func buildModeSupported(compiler, buildmode, goos, goarch string) bool { + // arm64 machine configured with 39-bit VMA) + func isUnsupportedVMASize(w *work) bool { + unsupportedVMA := []byte("unsupported VMA range") +- return w.dt.name == "race" && bytes.Contains(w.out.Bytes(), unsupportedVMA) ++ return strings.Contains(w.dt.name, "race") && bytes.Contains(w.out.Bytes(), unsupportedVMA) + } + + // isEnvSet reports whether the environment variable evar is +-- +2.20.1 + diff --git a/loongarch64/0051-runtime-race-update-race_linux_loong64.syso.patch b/loongarch64/0051-runtime-race-update-race_linux_loong64.syso.patch new file mode 100644 index 0000000000000000000000000000000000000000..fbea1fc7f5e1c72d1077639f4a66d979e3023569 --- /dev/null +++ b/loongarch64/0051-runtime-race-update-race_linux_loong64.syso.patch @@ -0,0 +1,1946 @@ +From e3ae08f6e5074081acedb218dd403bd87b2627be Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Tue, 12 Dec 2023 08:57:42 +0800 +Subject: [PATCH 51/51] runtime/race: update race_linux_loong64.syso + +Signed-off-by: Guoqi Chen +Change-Id: I74fcc442d307384adb16bf5c6698722390dc4d00 +--- + src/runtime/race/race_linux_loong64.syso | Bin 644528 -> 645456 bytes + 1 file changed, 0 insertions(+), 0 deletions(-) + +diff --git a/src/runtime/race/race_linux_loong64.syso b/src/runtime/race/race_linux_loong64.syso +index 677bff08c831db424ef2ccf73b85ef8c7e6192c3..6fdb3bad77751956e4c1ee6c0732ddcc3a7fc3dc 100644 +GIT binary patch +delta 165256 +zcmZ^s4_w`4^~b-L@#n7Lgozt>qFyE{Q<|{xZ;BIiIZ#xlm{g>oo1&sJrNp8xGfXm4 +z*2o8y43v@*3zXWbsjN^}En~KHCMqQ5R5F&U=oi-SobUNOBl~mwKOGuK}*B>r_M=x +zCdL=q{@)WW^sRa7f)fiC`2Mr~&K0ltPI~IoC!KY!ukoq-H=kPKE8YIg_b&4dZ(s7* +zzhcJkeQHtvH+{bH?GJxH6jN`u-?I6Xn8SVBH~ipQU(!=Q{K0!!zM}09zVc{{bLUg% +z9C*p+D|%|lAJ6gmhM&6hwUtZT9w*T$gFO{i +z`hCZm!3|VJ){dWT@ZBBsRqi;q&UfkpU+0b+ZuI>wHRiEZJI-qLQNz#J@#0;+&;rwY +zkFU-Qea$yxF8Z2p(~gB-_Z>)&dHe8=w+4LYSNlfHX$xacUs&ucO& +zHHPq47YU9foG@a3wkYN`-^h;p6JtK`k$TVKd8d>S^UUIy?L;pLj7@L>G?ixHc)~5)Sc`Zry=HT8Q~fOsn{Uo6x~ca1n}ZFv-g4co +zwKuKHTD5A`%HZwSH`ZDG;>*j+S2|AP=Gz*ty5;8jJFbHNRpNgYyI%!&s`T>PHV1F3 +zz4`ja>%Xx1*5GY-+;sIV_4M?rTZ1>%-g@Kb8nS}5pRc{XzV_<+&B0r44whek^XHm^ +zwKs1H*4E!%d&h0T+cq}_8*lyG=HRur+!{RpbJx_}c75$CZq4SK+2^Vw5pSiMIUs9} +zv*Z1*Ecn=2reoKFBoo}f(EpQX7qq1C^NDS~DnzuF{4hZJ*CWSg90NUM{gONwzR +z>diLR+N3BoyZP0K6cy$WziN`A(4?o(tNl_`nvMJ_*KFmYT8cI^loEG_uS;I_NKs^x +zk0q1CQWTmJe$^?(m=qII9F`)}^s-5*6irg>lp@XemXekwMX?lpQVdA3*W9r*Zi6|n +zG%l5r-Oc9XZefDU;<9~ng6hr2Wu){-F(AcGDMqA7HIvKYHc;EB;L&i4X(jl+F(I!QT+0AxMQpB1={Hjih +z7AfZ3B2ao(c>maG-)S};Pdn7a*^%WGvz27(WVe`-qT5U|9FSs6ii1)lnvxSpOO=8q +zB)@7gTe$F>UM_~+A~01NxymB5kF6@CsF9*kiWVt4rI?i>+iW|L9J-{Kl43>*#~fm< +zMv8hVI;3#S#vo}KQe;a}EJe8#EmE{g(Je*46vI-`?B*y3q}Xq^q|+-JO)h4nm~#s= +zmQKUyH~UzbmV%Bb{A$4Dte_ozCl|bXabY@ExaNnbFuPaKo|DT(s!2bIOmn&5otg{N +zauS*DGF$oiAV1$P&nNhKl9^=FT(c!3?pU)pBkpQCn9}pBIEf4z`_9W{AO>TkoSz!L +zlSy7*C76!V?q+40kR;P=D?6ED4a%z;vzuX|ImAV&6n#=unDkS~vdL^cg|zi%h>K1s +zrliO)lMJ&=@~PCwdQ-v$O*e*PQaGmfRC=|^EdqOMkrj$~Y6G8pV$D9biZ#AWH=bK` +zn;d?1*ewEGo5EdfyBbU_TMbGvVz$w%K-zVYjeE>)HXe{-!Yu-QH%2z@FzG9KU%NT7 +zJZd(Q%m;riy4@mBaeHLr3^T-5HBxj*anQo#(@3i_C0sPSMWClOa-dAJg{%UNUyUqR +znO+XkEk(Q8$FDMt?{q41rPwP)vB_aLD@B&6rB{LGb_tukKuX)m&1M_R1NTL)b$rL} +z)8h(!bQt+}7R~%VQ}S_|2pwk2$H}SffyhpUrk7-%8C-OkeQZ3|9oaZ&e5*(hye +z1M_Ft$Af8(efsv0sWzQ%f+={gcS9o6I)$ +zq5kB8j)QDG_VdWbbnIa{4 +zy`UN5qR=gJVq-DYJjRt#c&C{p??88aWVih$IiG@0xkZkDVPvb+D7?#T$&cGmmh`d6 +zZdpm;JUv#1dH%W-AvRW+N4W?&BngclW0=6rALdIWYl1i +z*HY0g#h6*SHf}>s?un688jiy2O)m#YHNG>cD3v0`zN>>W{8dH +zz)wYvQy95|*eJZwBp1=u;w0Bld1hqaYEx1~H6)o&6~&$UF+1~;&NjCe#jT<LMM&5zZPl#-fGB%e{vzz3yUFU~; +zpFsC%_z>#cB)pUMHQuaSPkFe#<;^C29p$=LifOZvUYVA4G*#QpR(c*7yfWOe1QiXN +zA(n?dvW-jErW`kDlFuQltlID(^HwX*iMyS8s+X;HUK81h-i#KsYg?B(5{ia$C5CZAFtw +zK9|}WYkJS6_Y>>Rjk_R_@#V;-&1|z_`E(SyCbT2wytsJZ@~Rf`Z$}tgRaJ{wu|Dp5 +zbin@AdbO3fB9PJ=IfX>i%T^gu^huFq_AzXhg5E~*t45P^ +zKJ75R^XYk-spZ0NwsAp+U{>7cbO0t)=6oY^brn(g{wRFF9O7_o-;5kC@mrC3XB1AC +zj2q&v3easG9?v72?avW2xq;fVM~Yb~I!tmY&B}h$TT1OEgbei-F+(g}?$ZX_SZBoog +zF=w_C4D=01HdCJWy>udDx$Q?HXCPifw@S83C +zir%eIk<yX`W`7rU9bMWZRdWKq&8avgvfi*Voc|HK|3Q=fN$Sjl +z9y!J@M+Z8^vpjx!xVLQ+9eh7YH(9C6$tosgmHEF<(&X$hC09_Yoo7ULO3602UJ1d=++=QZj@5@Ikir|*~;=x$XSr%7K%)F +zFIk>}?0ytWCRaeF%N3H#=qlCS=-BISU6B3Y)Qj%+Q}85kdg*TC;6YRJX{s&LBOm`U +zNv6(Z7PUCB%i-M-MxTLkm +zf)!sBZkq;P<>4oR2Td)<=%*N_tt~EC=D#>Rz&S9?_VDw;cX|R}1Wq4wM>}=pghwtj+X$PQcKRfCPdn`|SHRwXS$O-d1h4Y& +z&EWJYIRy&zd*s`WR6j{_?E#Ox)kduhudNL{)x+-tFZA&H!4H^EeS_|5^?T$eAqVjp +zo2~4p;51XdK|5W8M}7fv>L;y(lrMs3diWnq@4YlH$07H4G#nDsJkyNY2ivR`Y@GP*+Gv> +zfvut{tY&AO4dvmV0Ix7Z6fV%@kuQUMz)Z4S{HgG$wYD~s+`;Yj$hSbQ@$k=sH+?!h +z+?T-V{UC)iJ3FYoUk95ty~G09)!{A=Ku$ILST6lcxcr!{$@sRBJm`^s44IB2EGKz_ +z{}OVKsb#svBkzMeX10->Dm-cy_>9MX4S0pe{!H*T4=(|ql{oW9#!?71 +z9*0Z7M@-3fYR-&D{w(C6*+O!1TTOV{H=0SpW^j9)zwCfVy92ICwc$Q3Hl&B&4PIz` +zos>zHNB$P%5tBpm@(z#uDCCJ+b9HCjs*=>J!)x6Mz0Sj*1y8yr-2Qo!^R2jL3x5ll +zP8^)nPLKC%wpNo))@5~`An!mf_Hg-P*A-5WhyM%qV`eLd^V<(=ky>1kpFHMx&h$O#na9)2nKgol3$+<&bTw$*?qdH8iMAGWq8!NeVHesX`@lECL&WyqQESy9Sn +zGf9cA{fa9OJEh^ObC1ifa8f-LZ38bf+o;*e#UA-P#@9uAz?g~i2dX^U6L6g{hsd>T +zr$_!dWdC(e*!BzXVh{fnc&6D%RfcLj@+*+rJp2vt84v$6cv77cwoQXicW2Ba{On>gL{%=l9CE+Od5}hX%;SBH*+LR>4~rf +zu1#he*#yRJ46h&rnLgWQxxyoV12TOG$2Al_6qn?C$kaYW^X3sq2R#*jAH1hNyrx0$ +zpoi};+bEprc!-j3@o3M%=YSa^o8*HY`S<1!;q*VkD*LAJ8YjW&)6;HhTaQQn8)W*5 +z9m$~?kNhEI=jQOJu`BpBy^HYhMc`E)z68A3!vo;`!cRL=OAx|{$Kh0$U*NPG-?zCr +zYmRuhPx2rSn;eoudpz=akjFjz0`Mje-w3|R!>honJ%{_N!0UyZ7rq^r9BTF$-2|g{ +z4{rqT_V6!)S9!I_*N*HB(jLtA6J+y1(x$;dP$>l7wh2(@1S8gzWqZj6TJ#kAG +zUgDB3JB~^3rBlGm#1cO1vU|)Wy<`>NOIA0!|<2@S`ppqKp5MM<~o}Z(LGf2&~H!Xs1ahn}yFprZ0nX +zm`^@JHUAc@#TV{FpF@#L;5Epz9{EpZh~;-&`8lU5+}W8ilPv!Wa*Id)uStHC`ZP9! +z`E%wzdJ%fg@ea%qSN^rf*Kq>ig&rm7^51%>zyn;W!Pb`8&i{ +zI2RwuBNor-S0Im5$IrQP#Yf~-W{BmhPG;}2brR~+rwrn%Rh#E0CElF +zKbRqseg86(Y_){0EqD~_a6Gnq=*La+kI3qLw+LJXt1(!mAl6N$gscM1kf$Kqc7Mxk +zVflxUr#y#)bC4SmC)aFc +z`N~yNcjM8*6Cr=q46*zp$nB7A@K?}oOF!1p-Il~%x;$d +z3AxZCpI{ELym7SzZ-Q)7yWOM@liUNj53(JCUz&|1m%RnqkDNM@`B7^mYB#v;-;=?6 +z!0Tauff?f3Y9J>aE8NcOJIy4^gOD2_+hpD_$v-CfLt822O$bgGJ}lpnD>=L!j-^(!S|*LxBK%cc@pk0c%jJ7CE!^B0ma~VfR8U1V80Lii13hO +zf3;W+hZo^ch!cyQ-v0qFKS2y_JC^24Le1cfXuw(E_NR@uTPndTgB*u0=i4Nnb7Pn= +z&+h~ucOB@LpRj)%JeV%P@|VFkfoH+~L+}o8cM@=`Pc6U*L7<*@w@bjY-OF#sv0eQ+ +z@H%kY6Azhf;@}4SWRlrQoF*0-C^Y +z6&`X%AlM4J;ZQ->9lY78Gz#7XKH{p5^FDYXT}trQErqjett7M`yal`%ypk>n+!3Ad +ziEjC8t_6od-7H-g|m@(x-)@S&XF6CH%GB=2k%6j +zB6#i+9&*MYBte*g!vuH=cm{d$lsOD;XYv)`nds>t>>mOz1-CQ#CGaMf(>_`ZhyOy@ +z35QMKC1*>;Ufv3xMrT~!Yy(E4@Yr<{Ckys&!}ylNDhS08Y{gfA_kp`pfb8!A9{>*$ +z=cVVhh{W)>3#^dg0&tJ3-X1B&7{kH##4F$< +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 +z<J+3SqsZk2GEe-J~O +zS?)&Pd7^Nk%OQ6{?ty$4c<##r>M_M9!0k$HrLg}HJndBhiQu`np?Yu(i&H23G{-K} +zR*YsEIK+-i1WX|3PiEr*%J*Z95^pDDJ3$MQd$o_J0yY^iRG2ZSr +z>95gdn;C5v` +z+p+%xw=46FBGH^?so1W}XJ_U +z`RIKFx3~|7;6m63!N)!PEaL9DB;|Ni42R3%&;mXKz7@RT1hG#8?+0%OUl0Bk_!#&m +z@ML;pvqC-x;P%souDg%~Zh>7vu*DVWY#W8Y4sKT#+=)0#C@jaRPZuzNIOl?=t`Kg& +z7U0yAkna2iX7gXN`PN4q#N=70deWCg*f|%5%xC(rAaY9NezbXz$#7 +z3A}NwPN2l()MF|_x*PN%a9S8UguoQf0s2D9Z) +zbSi9yY?qiEj}`ex;LRH)T!mogb@095L4;d;w^TFzNwK%@#MgoctAyKuxL$b3X@`&z +zFEwn1gI&53`8eCb$F2%b=y_W~jc|Joo&~q7SN5R+C)1E~e~i_#{i69VDPC%}y+s}J +zAn7Zd`(RClgmvD6U;Whr>_O<sj_b<^&imBiC&q35?L$Fi@`ixrOfND@DXvt5#N8bOb1XZr__*pDudr|qWX&(x+5 +zT>0T6vhDW^z9G5T^*d)5ipf{No4zFR$=%%^1CRZ(@F4gY@fA)lUeVbOX`Okm8~-%N +zuKH;&);=eK(~Lk3aQ&|F{e|A+Ev6~LePmYywFiu|!D~WN!7SXaBEG`;?veWKB`mFS +zNZ|q(ckpe)=_40rei+hs=2?E116uE~mqJJu-R(Lekw*f#tsgZw9v~uo&9O+&#g= +zj{|RPlQ@}(zY4q?+)aq;cOHh2_BC;shQrI?{(FR1g0Hw=Dy{}E1iuKp6Wq?$+rX#6 +zQ?TnlNZh^NwM)EKAkgb@uuHtQf(L1j<`&x}UJpoKP7V0LeFE&U3>GIu`W@x&cW4g(5wcwjwhvRh^Z{`jc}Vi|BivQs +zd%&~7`PQ;KqTm$P-5v$+=$1IC;6D?7n&TDrk+8zq0W-(hkK-Aw{QfTG`ve{7xSoE* +zv(0}E+^$S}5dF32A+b;Gk@{N@co}#XI2{Pw?R;>%b}hQYX%bHNiF+kbIV$)89GV^# +zZWDSH+^%NZgbEVqLX{g}SF^PpyD|#D5WJ<2<1d>3No1qxeUCcidFXce+ji758HLY* +zH-A_1t&qYw{@aq5m#+ig`#mwtMEuVP4>?|;2@Z$h&;y4a@Xp61knP!F@GkH^*uMr| +z)Gzks;0x$v#vRz^@+;;)7hMNo1`c*%#>c_u9+yDU9UJOy7Mpa(su;dX_NDaR6GrygbHp4 +zp98M}?*X?<9NPoe%f#Iyyj|ni9w83Gq4hnf*p6`;U1{=M*$fw>T`SpssGUY##fkQRAPuOKFir)y +zT|9XpM(U?Sl{oDBr#RROz5%`md;kgk9K7-0;r71^g4rfi0dALI-ielVf!j5f+b}8q2X5C`?uUKW_oUvCT|RjR!j%x(j+LfX +zO9P!=@TsN3Z3{-g?E=g8&L@8+=gt*;d}dF|3m+4X1(vD*(WM)#fSWO6sJH=q>Uc3s +zjg?Gyg4-pRbJ5jrgWDySGr*Tq(>bBaOodh9aIvuMY4;C4CYO2oMh+%CsljP~6r{4{6$YN=qS6wZBc +zunRQzBhYuuA_J`x;>5XRN2YfXG +zx1{E9w-Io=zH<$-cpu!Z?>y_5a3|7R5bplgHi@$KKJ^``APDX!W +zD0D0Ad%zF>QtU0?1#VY~w)|D_xiMwW$ESZnuqc8%25#4l +zw)|>vyKb~?*cXVq=Lakt?R24K--Lr*H+mHOC*VzSG8sm|{|Igul0LXd#-{v-(tu#9 +z*q39-Mv1R*p66HGe#beC$#vY1#GxJz^%(mKaJvL`CMv!Q+`-b*_C&UW_zGu_8=D{Y +zVxL<+$ow})_*}Bo?^Kh(v)8U+9YjLk0k>;d+e={nNS^Jxvc%B7>rNWt3SK-?K?W+m +zjyT)TeO&BQVbK+Wkg`gIb_g%HfyRymO2o4%*!RHxF!(X_7N0AyD_^&Op9G$Qe@tiJ +z{ar+yzl;KS9Ia1_GktfA!De|R|VEJ$m_X6=NkeK;WLxK1eh(m$IEGSs)hAEI} +z1$pLgDe<)-@n0(*YsF)&c&ru6wUW$Qsduf^yVk8KFWap*FWZfhm+iXeWxK)hvfU_o +z*{*wDwi_%j+l`W!?MBJV$vKvD%FC8$IT9@=&%AzY{BarLks}^C@DR(@V!1lUoVGOn +zINxe>&eHhu)#9*59M*`#8ga;#oN^`6Tyf9MHKR-8(_`}T%*0X}9})A!G*23nC#}en +zpm|b7p2W_R*fOAb`Qnf-QSv29zPRU0C*+H}3}IfrM3F(uD_DJ!+ZQsFc`|r;1>z{f +zoL7)*?q3$49g^6EQemM~Q7D#$l4zmSR47%fmG%}&zH22z8Nz%Fp$vAOjB=iga=wgY +zz6@`^3}}9KUL_}*pW|kcFGHCxLzutX%_3ihB7e1;O#W&&i~QAY_4#Yu>hssQIpwdB +zC~MZ3$5P|dLpg3^@>he3ql{s`j9R{oVZMxLKK<&FlgV}aB0tw{c7Cp8K|hCcHK{jO +zg5^oQd6I<;Z+@OQQ5Z0%?*AXub?~eqlj^+up)L +zlenDriae9PJU)0zfec@P3}%6hVu9?d1+sS*Wapbpm&ZSxoa;`CHL?p+kz;(v#itz2 +znXJikyPAqMCgZsH>yMW%N0;TvF(Xe77I|yU&g0_KLeh{NX^8B|`8hIDIhZKWq~l~K +z&(D$8$xfcXS{&rKl`lI)et`^TfsC+t%Px~I$Gd!*^VvN5GTZZIwin3pr$8ocflS&0 +zIqnqX@y?~^AMW_@ +z@%RE?;8d& +zN8Vt3g3ou6IeRF6gYOb^7Z;y2za5JIPiPa~hp_uQxDMigyP|OUHw=zjowhH+8w78h +zO()E!_nwMBAw1*;(!$7zksbC%;VHp+`=eF2Whh>)c(&p-3AnW65DjMEQ}N5nnxK~w +z`YA3TSndGl2I_qK!8Z{9nX;#Ur#Ku>3+P928%rm9+Bn>`D!tMbE_QjH;?0WRs5t#! +zT&gBCs^lA#JQsxzo-|*Lwx3b_T{T=88T0mfZ}=v9E`$K +zGUwyy_(9@s`_Cm^SI`;7p-*vbe?W0v!Ia|KK6d4igidj^L(;qumQb6i-9dA;9daqT +z-$Q#$zl3q7mD?uOfsLmfsmEznd_Zw+zf1AYD|;-Cv)bXKct{DeaNq;5=B1~jVpFm+ +ze%Ytk?M~%Z0h!%2AGU798`}QmTkcu;` +zxV9e`F2{{WlmlHrxf@rYc?~!Z!uOT^CU71E&Fhu@50rg_vj2fT{5PB0pHY9cK(~|A +zO@oV6uD-#7;@VB=wer3*+85}$G*>{e{9RO*@alFY~QNxGU-33xnP%L;iylj +zMog>Po>ZK!?%a*-f1-G)*-GI8<&e2;KUY(w&J3|!uVniTcMeC3)wA59Oak +zFgQ;d&HX0lY1%1La=F>^<<(!RaB1M&y_;3IV#V!^O7^$Q#jyP|%D!6J|5EWL;j&Xa +zrv$s`3kP~Z@$x*bMlK?Ls(78^dlhd~{5OjCEB>>D%Oog2jw|7}%3)4%T|s8P_;R8z +zD*H+^^bB=uhmwD<EDE!>DX6P#YrN#S6i9~qwr$I`5({O +z?SSICW3vjyg8SnQeU(D*@!gFD?XV{bPg^^0Z`4Ej4DAp6rDL= +zfj&^TofVn);1itaRV;T$}8| +ze^d2TmCW-Q#oeh2d(D%$r)k?jfBG^YMY!4Ui}>Ww0F1cM&WY!-t0bX&KUML|R1)Q% +zn77xwlUqldH$JbKM4ODtLM*TD_+4`p8+g*Qau9g6=)k4m?x{Uwb`4|GmL +z_u4qP_W&~i?mfUvt9qVQ`5spM{}lIM;I=R1UW)3=lSC2RhCi(wlEArQZC?oPy(}tH +z_WH7@Ka7W@m-%rJ!bgTqaXmjrR3M$uG&m>pp=!X4vOmJPHFK(h8PzMm)-$I;aebLKpt!alQ5^R1 +zZsbHW^a4$(qzb90lnVQ0VkY+gkno7;DU}6#@02Qz!mGi(acYEz+#7?sg8C>94N)p+ +zj$+>u#lAhv{zh)AY`mltZ{C)5hdGE1KlVhiuh}RzybtTc?k1D-E4te6fXoA~&$0A> +z7)drAzl!&Vcrcz*=h0#1Gp-I7_P>RCW7&Tb%KQywZ~rNR*FN!5GNg?;U02{0y~t9+ +zscLrG<%qnaS`K?}AJ&s)$y)Mwo`H4h(5*jMUed;p`6p{D%V6@ +z@^ena;Y}|JA#kg+ltZK9dY5bp4@6$F?J_05p*?97G7sJhs(pJ^xHD8WQ;M%vJgri~ +zay#-A&jjaoXr3)x4$fqO$leJ +z3T73zUoqh-V?Q}x@j7LnsCbFuDT;r=&KSN$Z~ryw271oBUcbbpPZkdCr4hl5Le;uqLH;_kSDA3l1N!+&Zu8(xf0E=z?G=lE;YkPL91A?K;&O2N6|zftxTruRi^ +zQ)LvlM#c4f=u=$x`<^I#T5&z!Vyh@0du6VLG!fk6o#wew_ +z)G)u{yyHH&-wpB +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 +z6=A{6`%9=VrK& +zak<40D7PZT^~WO3;M@gesta0-FNJ!j9WwW?mg&7M$)Ro)Rrhc9cO?t&8LAZAdxjbV +z=dAUKVt*9-gThz4d#iSsj^f~aPZHW-l8;ST=HASqi~3c^CM;d9&+LgX<2?S8V6G(H +zR3A%2nqnr&kM^mpTx6Q$rF0O;Qr5cl?Y1(Ca-r%|y7fWcfgZ@*r&^}3dQsHHgJDt4 +z#Y-uN@}-o+PRU`9*+OP?JYwtG17X(ENPe7EyjRTw|6^jqEqp}r3~-(Y7pa^xjc*y{ +zoDG?C)-rt>Me^bz6_w62H!q`{>zC09y;_B>P+{xLHu4KKsIXdY3X3Nh^JACdkE-kk +z6i-lmr{ez?KOg6yaC2&ELUL#tM%*@iFVpE42kt8U0a7eDPj3A|ksq8Vx8_+YPM=?5 +z@?({7Sx7*?ud7ypH1AV^^gDzJ#otVruV7B`*Ax$aUu?Kx@5P@r@6Z({%<}>84TLtT +zQ5-Z|0yH^xK`!;kqo$YS&>j_4?aE)J{^JAUj$1C0i&f)Z}Il4MIfx`7Ew?hf@;rbQVpGys@a960l7&coe +zTwnw;ca@g+m?4(;s;IiF4wy-jL*vR@H@*Hxk{It3y3MVM>o)f(u9F`C=f2R{4GK56 +zpGXIcT`=-CfevaX(iv}$icM#{H%_GeZTv*q-+BfmNe=#L)iVRe7o?6JhRk8Lyc67e +z02)7_D7NF%@I{+1}Sohja-b6`VU6&nE~hi;!H-4l1`g5lN2jt +z|6v{Xi_RqWNy+d+D)c$h4_@x!h2R`V_hYf*`XsboxO~}JS5N^5&R6$%rRiNk`R-Nm +z2Bc5P&~b{NatpUdb^W`d@Tn+#MsXcKOLl5ga8g2YSvK}?9)qwP!MPLeQ^_@fbDPdo +zbC%}KNi-W;RX8oTo82sTsHl2xZZ(HU4t3yY$H{y~1@8mrWPY7M57>4ou9tub{zMGe +zUcYlMQhZ1?sz$in_1Cuy*6)x&+}diDP^lTppypIU=6tnWZ6--xTmzZYpdJ5&lWE6K +zJDGNT|IYca`s*zzrsQPW@zWr4SS<&^C7y)f$4nLO#ChywnO+LFI9s_5)A5JX80R!9 +ze=5e@I{i(^8sj^K(x`*XX=u3~+?z(t&*sBjsXB}9^-{P%17r@TWxDxG^5SO5=&Tn{ +zp)B{FLhohhE-&f64s(bLx~WS=s5{JB>gC7GpUZQOqQ6->sJK2Kj6~rByXNDxsu>r2 +z#^vX_JEyK-L>k9Di}o5@qDQzjsLJB3yZ$fQo0R#9mNU7SgsQl3eja@cjR +zwg1tF-D^~r`=6EcnO~)NBDiuPEG#FV?qK<*{fp?|q +z#QorW;MKhJ7X)bY@?BAQ<1bxvxhbtXJvizL9~q=Qifj9d=OWwhRb1PTgL8M)#x4?P +zew;Arr%`_$gwEYxtGa*2Y$Q2!ScTO`LHXx4AN`(c&GS-&cT!I)uG7o;vcdsn_=F7j8DJqFXJ) +z%2}^EKC1W)>Y%b$@vBu5S$m~1oV0#-Tnx@hY*vk2FWkIBNd!t^#66*n=wA$-K@*}< +z#iqmax-)1(6rDkb=W4TW6`ic=Of8x5r<_#eG=^DAR{Yom&Y4`NGHG^$1lm*%TJDe> +zI>VxxRoRq7RyO6(Ejjd=joFj~y{DiYLW5z}Du>_7bMB?PRj;-wev9hWPQ@Qnyj$_R +zRGico-S~3e)D_H%@R39H)bAuA?v(3QryMjTIkcx9hRg$_FJgC=J+WtpYIX*t)_lDw`kO4Rj= +z>;1nnjGGr%^YLdj4RxJc9nG^t6qY_L +zY&=TTjC~UQLMrsSaGBuc9$sbkQEj1W$lT(3)gg7@Jc-u(=>gkxlyE68iGjD8TyXC2 +zn^gQl;pVzLI?@!w$Xi*3*_KD|lSlIKKKW)9pel+_ovQE_WnXU&QLI1{WNxpPTTFUB +z?E|eUs-8D(;M}_(CP-8Hu^pV7t$B~xO5xV^soJ)vWcH|Pbnos5=iVBobxQJSf=%Zq +zBrYCT!fmnUgaQ)M3TU66RyEwJYM3!41#~P3{+_dxtE%;W^JVsHX1`4kxF-EG;d;|c +zer1i2xtp}yq~huR8BpQ$JLy5=E2LhZP;OsT-ABL2V>xR-=O{lT`J&?KA +zw7eHwj>sfpJE*u$ls@LBaG^OB?(?c!V*eoi-rc1boZI(Hwa=D=bNe)J0O!`+uHrWe +zH_OhXdn8RT@>bRyC1|S(+N6TEnJs5ho7$s<>rh;OS7^WD`pZ~TitDf5B)u$s!)>}l +zRi7f(UlS^h^aU2U=&^$g%^W+ +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 +zXl{20#az<~uN>vi+C(+Vxm+Eo& +zWxPpns-8x;GYBVNzk0Q(o<}&E7u^Xl*DS*;Rj+_Ei#2djec!7^_4=!G^J+HDpsH7q +zM&e!p@>03~1D*t5m9y&C#L7@$_V_|C24@*cjcfd0AWoUP^EFb2N`#}i+MO12O&z?l +z3@LDyp#faVP}3%5sBV+NZ#ILbv4%9{M&LFX{0=i~HP+;;TKer8{BHPVyk2ms?nk&^ +zBbhBOJ}6?!aqB^*Fpz^#nMxm;x8ox4l+W_rF$D&zeD1uOp2GcS_>yTQak% +zUYGM8>9XIm9^BeZ9qqzJNP;&TfLc8$A+9$zb;m` +zCbP$vNDDX1%BHW_ef0L+QK{%S_Hghr8Y``m3 +zZ-O(6ZE#Wj*_%Z5_)VfZxh{I-rK-1(Mu9smarPCPSygZ4xP7mWsV*~ne5@kh9M)hUFdS#CBKb4?SxQgt&pRkwnR>IWrzxBYri-C+h*y^S=w-GMiV>RvOe +z>TS6c{f3z80r+LSA#kc5LAVDHZq%KUa77acN3%REMa(rb@JiLQ;LKtkTvT7(A*$;; +zMD>yxRCQvn{^4J%?s$i&UN^Id7+&%awPbO(=1nM%#B`I%k*C69l0$HZJyiEu1a6*$wb1(!12eO$^ke_YB` +zZwAdH2W669T9Y{YTFk6zJi46xGFMP}O-zqs*O@ +zIQuHhtg7?&y1S*{F4fiW%XoF*R9%m77a^Sd`tO@Xbu+@z-0H3ob4@$Ea;!VRnMD`4 +zsQ%iUMfLQXMRl(kRCPYmkcT@-oP9%PR@M1?-R1ufQ#}g5j5iKW)sqOfAK~P?IR7B3 +zXAzF(d3UFnYZl>^s+Yi-#R|Bn-uI89I`1Dv^|~2Ubpg`YatHrWR40BXTwbcWV6S_< +z^xHMod1j9v>I%TAy4bjedj!JCZMqV!s2t&FmLHfAb4@k8QgtmjRj0s3^$lI3y17eK +zH=04yC`1}9?nIZUZZos0F5K(BCjEA)?u1{)>jtOlUW6+`xIVZ4Euwl5;b2F@%dz(w_E-y*8V-y*7~&7i7_k%rs^BysjFm|0a9?{)j$8dJRtzl^sEPSxuO +zcNxNMxMOb>)!PV1vpnHM%r$u%l7_tEyIDRsvnT`?)elPcZu_mGy3`D+x&&#+O+arG +z)m3Iz)g^n~4R4F7u7h93s|Tm*MuafQ#y@ +zyG3<Uo5t +zdC?sdbImfmQuPWrvseQc)pxvIR1d#hFKn1WRhJ=+#Qg%~rE(t+o&+!3>mC$GyUI{t +z_W1Tz49+r?8rS$wK%6pn&CODVN`#}i+MN({O&z?l3@LDyp#faVaNo^RhV`3e@SDw` +zX_O-kx#uS>gWq9htw#A?cXc|Zx*L8OuNR!E`w{NR2shyFlyF7E2uJg%J1yp#ad@Tb +z32+X<#yT*DIei?5aoT@hw?jXW# +zx%(wtQO@rrj=VG+&GJC=6Qa7n%<=855S&?*fQ#zePKfIM6Qa7@463>kX;isW5@%nn +znKg~dz3x8gw@Yo- +zWp|gDYgXZvs@K4o#Rj;jeoC*XF7Fl9+h$PJ)ks602G%R8^Zy`RUaGo!ue(k9?HcQ1 +zv&VO{QgEs+H?HBXM7RofM#2?UBOJ~0OpUwyk>IQJCZUPt8H@{0%cfU(ix0*rI +zs6`qb?oNrbuglD;x^}O-NBZqj-3z~r*AGtBg9vvB;fCD7cZ=##grj-f9TRiSB)n4f +z6gab(0Tzr@+MVrErcCvUjl6T2?44!?}I2~O492=_dM +zOKeI2d1)HY2hTIE@vXhTE>Yl4y+`U$Z1(v6Rsznv%D|-#m-k5>iu;}tEgTxv#M^AcjD4-m+DRUWxQ>0s?Pae +zaU?GdcOAkd-TvD|b%B{R9L>e}{fY{5DZtZ3a!F8EK^4 +zX^FG1!OWUQv%C|3e@t~V{4!oEI90bJ-1P|8;f}puRCgmB&AslVm}~msm18{s&Mbz& +zMfHP{z1x1js2(+gs%}9V6Yju(sGc&js&0{Y;sY_&v+&D!^Wapyh;YXcZpodJa7C*K +zNAtQnBj%b-c%|wsaAuMCKS^6&IyXf1)h9)D{Yg=sX9iW>iZlw{@spyu#LTL?Ro;n9 +zzg;uD9DW(E5}c~55$;BWt95%mAgb#Tj^;*pP|P*W@JiJ!;LM^8TvXrj0Z~2t0a4v) +z236gLGU~XP|8ZrMK +zZD!$AYBsJ3y#ayS5P-Y` +zex40K1%LAX^fNU+&!X^8>RDd;;Ta8G)W5!yoq(S=!p{`^2=}#>zKIz)VqI3j`3T~51b7nyY=Cz_ +z{T};Y{(Lz5soT4^uBHy-@zvC6JgQt8nNFKQ6M8E$oiVNnkno>=&E^Gw9ciezWLDK4(0h@DezOZXN#L?*03V6B};Nhh<0KLL9TJ +z9JzzS3)Q?iQaQ%sBb79+`Z?lx;Pg}Ac{;j6#}38TAs)EIcsy_^0^E!OmVq;HCH&vK +zH?30rs~QG&s5KrBT!#Q@1Wtj|PXqk#wAc7eFt9_j@p#}i=l*9-Wqj@!&AsF%j!!Q-vi^O>Wu3I;$yW^#&ulD +zn~bY~zP*L=r@dOupbGlrqVp%^Jc18$>_W#|prjj|&ynndKeitLXZu0p*ungEI}gL@ +z+)TRijYM#skgR~G&_3^>VW`(Iq=m+{g8bcu;)mMdPD@BbI~<({M_u3*2s{b?O|;+4 +z!mBQ{L{&dKbY%>}?}DQd@FybhIQS8?p9Fsr+D{qJ2;Mo|mE`%1G6snsy#|fzm{IXi +zmiBoUg(2W!bHex$@$=p=x6+A87~U5Q@?&D&QEGRG#2h%=&l|_&iUcgce?R;$MqKo3 +zMs&1-0PL^^&i3oZ +z%&cQev-}>9crDt@;#HnOt|@FsPSQE~p)9XKj687uW<QG5ZXJ$@?KbQM)5cTE-DRJX +z>BGzZi)Pj-`v~8kkqb^DhYsZp30Q0Ow*aHm=Ipz7(A8%ZwjZ{oKjQ5rDf) +z1vnj5ApqOgg0p>{aTTm_ca~2I0k}ujgVRw10`4 +z*Wvn&>!c%JHLjCx0F!RRxDE|@&ZRoUqF*y&;DX5DIafzH_`R4!-QYh1?+2&`Nk^GcwBio+A~nSajnQnRHVtcR)oC8b9coTa`!&= +z|73DxUj1;yw;}^>&llt@VBXAHNd6?(I{4qAFeODn-*ws$xF=7_?(_kq-HUF_ +zZp?Umd!IC}<>L0f2tQ2-zjStczdBaX;RbYAHLm%75Q(lC*ZPvL!_S{k-YxhUgrDsq +zTpgn!`AA>DxUzENIuJ~>5_}&7RD+*JLa7W_{ojM3-VE`;jhPP8{)cGa1bz_$w}F2b +z?Ym-pXLss1Lp<;RI#j~Zpz-(-YY2XL#2N#~TzO?;1p!`w0ITQjkk~}~uc7_6ah)r- +zV~i8-%)jeJgGYrW!2@6toF|Lr;G9Yo#^bsxjcfg=yTS9zqjx1ALS9YQAtfC?rCSS_8M224(|Hkj(h;^htPfy?T!1nFk}V|OyLu7^iOa!4M*g2@WV}h4V;@y +zd$D`*mvb+X-&i{|C2twJiv4(LdHxyUdfag_r+dw;S@P&UW?akjVRV~-JMw9?=T +z7mogv8=>frI`ExSZLu^Uz(-KPM))Uhx(p|HoWRWpz=hR<0CyljEBMtoA?!e4w(rVt +zU2*KtZHD;N=rexS>5g&r^Cb7eugHjUUgllyM@TFFQRG`-TnkQKXk5dy9w~4x=tgim +zx9}s{3!d&Is$TsjCwBIxy +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 +z#-$SbWG-jI%5B|l&mVOUyVm5eR6HjQh2 +zd2+pFTLmmqUxOo# +z@dh{pbY34S%HzxexIYtkkw}qO^9@1qFHq7J@Ll)z8rMp&eTO^#fGny`GiyP3E<8bw +zxjJQBH;1FxWoC@)0FftN;nUUjJdosgF7Li#hI;Fu2|W%0y0h?pa29+JoCO~Ozl868 +zhRqO9XdWGyP^u-296xVp%EH^hcOFQ1ov7@AfeQMJ$4lLBJYMQ4`1w)p?Vn9v@>m`p +zR?Mtx@t2r5tGDk@URtznR-GoaZr*+EMvxXCXi3S&&P7zZRaH~Nlzo2 +z8MA8|8KfrLpV2$0Q7&L)l7r#v7F?kdpg}7{j1xZl)n!4zzfUM3om?9SzqL&Xu!-m3^Wf#UWDQ_`gV23K>@dJK?aa{>Ki*7WoE8z+5Be_!S?OYAuUp;U)2Hpq$H{ktr +z2R>#zey|%ydpoa)P6QKE2yiJJ&7R#M%5)9wUz^ONpGa(?J$2{3ItFq3D6MyfkpkDc$%pCAtms5>v7`86}XZu3W-RCZnAJd?mChMRR>*-1P +z!(QFsyqTgGoJ+6IxbCKW!{2XQH*@2Di7mhpKWkhDXMn9Ny!>@x{xH#M@T;+6x?Xo- +zDD{SW;l*-z*}#hFML({XA>%qi_oMx=aUBWr(JX!@jH6J#Ad_Z5rNpJ&(E&#kxN2Mz +z`aKd_H?9ehZ@>?QRkY*qQie*^w};Ad)ii;>5bgWGUj#k|&f96GGFh)m;+$I0?^_O7vX3)~9A@gc5u8ZVfb2C&f@f+8%yatM! +z(Vl@@jO!4i{UZ~D=)h7BxdZZ6`RIt5H7{PKoJKe9;%neMd~LWB;_jteaL3z15^o4~ +zxz^4BRBXO+m7k9~78}>Ju07A){IJ;JyB_@>hJH=p4Jca|IOjt*;&51c(B5t=@X|Bc6&YE#FNP{BW7O*UHxtrU3+0&`7vy1O1O`_dfD +z{BW-Bc*vKR@am20mavKN4aPM*c_aMrgMcQ_{q<+QCu~Ir25vX5fq83Ihj9%|-U&Yp +z+y(xZ+?{nPk7R~{_lnJce;iXR@y1Xgj%YbJH`7Y+ouiJ%?}UMl2Ebp8IXrAUK4nIX +z$EQr;o6enRweU#4&PfJnv<_P8KVpnqjBBaMTM=N_6a%OK!p@z9(g{9lvC0gpjMr7G +zjjJ;9M&p|3|02;QRTka`&LPY13VwKYSPxFYdFi)= +z4*bM0-*{Yc3EJ~f1r6Ze&lP$0>Hz1%D|?JbzW~gPM$v)$+LUoE_5Y#N)8Ov}pE0gO +z!1ilV`9 +z0H>U7gkk%fxB2WeJliKd_uCug +zFVJ1)xqoy5g;ZDv9a46v0%!Ybl`2d+baZA_pPIESSX0ocA7e5buG&=xbq +z15bg!3^Tg$=CC8$gMXqKRBT)olb0A*|4r~yA^Z{AQ^)d?-lzU=qSEcZT&|yYpx?{U +zug`eATYuE8Xf{i?b$3X;ZkSoK^iNZYVkWBWEuwl=o=nt6hH7{6isYsHYVi*8`U~7W +zmnSbd?~4hy?~3FlZu#!4;-_hS +z#`Oe)e89M7{a2K05dO)BJog7Wp8O442dx+P=@A4-;JZGf;CsNwjq5nE{UrFF^Kqb? +zGDCcz=D}Zu`sTmGS5DjWDS9Q~uSWY?<65DecgkAEIx}ddI|ljpARIBk5FC9>hAi_M +zb*B#`FMaG7x-tF?_=dab(K7gLNN)}1*Me_?zcV)zOBVY(gZygnYVZdz9u45;|MJLN +zml?D!=b=NlyGwE`>NT@ghi3W0nMxRdTb?gXg1-)Ori|;n=B*ji#&tl*=g^*?h|GKL +zZ`q)sxYyT31CW;(*8t?L#&sI8?(N|FQQz)ee)vS^cZC7rJMu;2THj{e#=7JVl}deA +z&8+pMdEFfsb9w__S>J+phiEsUz9r!NXsjQcG6%sqjg~yO6Jh9IMF%=s2dAUF_k={R +zgr7R_8t?}2*It1Ap$P^C=mMvs6>uiH22MZueIe1Eg{kpNVBnj^QseQdTy8u*m8;O6 +zGq4)%$$N!I`gLl)8Dl(e9hC26D*s*qXQJE2l# +zt;G3I+-h7aDm<*eHaOz%=5&Em!4NnvKrex}BhhW}AWY(y^ao|ZAV2O3PQ}&WRNM;A +z)zJmc_qo%`3#1G>mQ)~DFrKJaFsz?ekZ)jQUl((F#mrhrnpY8yGoC%_qC(H(q}$X_zE%1_|1w(5?F`PjOdRX)ud@JjjR +z?+^0%BP&(LH4Lv4Rl7q^mMrSbtYK)bcPGl_O-lp3GFmgd@{`&Y@3jqHY3_);7IkLv +zDqqo;pmH0NrnaZYozeg6^O^K#=`(;#_&$5kXEKaTXdaEcrpK~)EgT5dd^HwX3Y?2| +z#CZG&F={-1gc$eyMbTT(Tx=f`)+oA%F$@pI^e!{50AE#9ezLTg<{&E=TsLFVJlc+Wx-z4gc>)N^idqll) +zT|(py!rk`MlF3~^6xeC4wf;P8_kh0^Wf%p&349!!Ti-Oewf8%~91J`4ktCMES)O&{ +z@$zgKkC$i5xR&RkC{N<{Qa@l?9~yFQ4+B}3bg!?Jy^?3u1!h-=ypB<5T>X((p#3SF +zR9B%rd986BiBBcvkId~6b!JfId;^m*uFA>nYFOYo3wZ@3yMsayBmr +z&Z5`5FdG()>pahgm?dytN?kRs>ezlA+}isIv0;X|>`icf3cYPy6WWi2690Veswa(W +zLTsP^&sdNghXU&mPpA+99)`fh;Pg|9z-(Wh;i{h7HvHskR`yTETmLQ@|O>jjCX6SFY98y!}_-vhp7Jid8v8;@_^ +zso@ZqewrdK`c(l99o9ih_i&7HC-@(6_~|jOm1FxpaJKI^9#xJ%!7>WNEl|9Wg)bV{ +zN*v9VKkT()Tq{9d{*h3L$6Nbo{HyK=hN@)7jr^nv_%pyeJ{sCH(Oz)+Sp}z`t&i@x +zB#Ne`z7TI(w%z_}*(H-BK8{wF=6rBgw!nCNP8J%EPnlxl8lJmnspn^3t1q(-nh-nm +z8`r?^$H>irS7C&oTtE^*-#t +z-Qd4{NWy)zHhDo&uR&d_Y~1hes!d+%st(D?4^OcM5p)E~C%~D^0yxev6WicyUosYk +z)VQBZ%`kinfm^|OraA%sakQTW=VC~F$_Lh}mCApaSNW%&>J3^U8k((xmY;7J<-Uu< +za%wvWe~->MlfQ@EAu*@N%&cB%F8*}T&w5pXQ%)WDTOhL^oHExu_a6ZAjJ)_?&mFiK +z{3-nb;hFV7^G|P`2i#ffO#cTC=C?F?jGdOQoVnE**AXBeg`chq3d6{4!|?0#-968fD;Iy4 +z8|-bh!gZWXAO%9KH5t@tQLc>dvKE2F^={_2AqR +z`aSnEjx%c*9T;F8oJ(NaxDM=@^W+bE<(&%UA}=(qa$F3^l_%USqZ7M}C@Fdp<@2EOZ9*KoEWszFN@-kyb*d?5tp +z1+aQ>9vlY0@YK+Oh7ojNVJF@FQnaIUX4YxXo8dOljlwsU +z#^a~r<5_t5m(ML={41VoJsxpBP6y-}4fV1mPMKW`@(3KH`#o>N*L?>~hy`vjt~xJ)j#h9!N~y!R>Sp^c@L%yh>25Q` +zE73d?65`CMzU$mP=Nsqd{l-mdz10_R2nm` +zD}$dXj(dLgM~$=AK`U68si6FO!MIkAe9^d$C_hwRf*(F_Yz2PK@DXlnaKwi`Z5od& +zOU#B!d=|&M9OLo!Rp0dOcX2%ftNd1Q#KlmTg*Rs5tyy^ae`fJ7JURo6uflrkphHlE +zA!q>SDr`2cL&Ns1;B4P!T;is8?ML0guxnfBHLeLg5()Jo0C_+Ba83+>`wtEM8E|40 +z1`feI_~$Ujg>$~7@%_Hc_^vUQq`CsSe1IBg8c#bj$P612c6fiyS +z{a>e!xZ(AF#~b22d3WFpkZ)Xv=1~}$0(b0M*?mgPtW$&LGIvtUuCFn6!K5lnm}=wk +z!Zu`S-vj=vTnTQkA#gio^EZI6nL%|FL&tigBfVv2)j@OOyS^;SImL5~YZzdiYOUw~i(U*|XB{+O25vAOPqYb~?VF9q6K#Y4%XmjdI}CKxg#eeKfIZ-B-)lS` +zcyb|3w4I5m%e3mWH^kRmwek4W==+{;ALrXy_~L(uz?|Vzi+d8!llakf=TqDSzJKlx +zoyK)&E=MK0-2RuzlIS(Fju6fL?vR+%1Mte3vkcDk*0b>HAB607>L?*6jB9qs?7Uh2 +znV9t4{qSXS{ylAtG)Fd?b$gnU@@RMXzS3POD9w~=e|YZDGvI7ruoT*Vo&`1@AMs-2 +z7+JrMx5CklNmb=vZQx%(fUztA#?KBAIV$~;PZWV8Ui;(pxeaSS&cc6kZeI0M&vjA! +z8xmbIu7h?3rqptVyDwdrytru1{#S>M%{JVb>twfWdUHU66h=h=O$8WTm`dzIXK%_oUwt5?>ddvK{==3 +z061sV0ywAgl5rJq00LHwM^7E3VGWM>lQxAv4@1KMJ>Xo{jsFwclNYZBu70BLOiFTz +zN*dggn`3Ku0%rPa`$ZTbPO)}yR=mr2d`k9!TYEn>dd(0Yp&@V{p2rfYN&x7rVyALa@j9KWm%y)a3;E79E(9BB@!E%_Nt#962I~R;vG`PRq +zxE`DWnvAP3wr>H~_P+kosMQSdA?Pw5PiPbEzld#NZY@-33cTyrfqyCRbYc^RF9$k4^WcN<)ASqlBl=Y_4Ly;;^RJ@A5I6%T)7r=RdSTi0!RIVG34_U!|A@H-ze>DDOF!00lI&f}~DdX_~ZD@aEQp#$t4&yp` +zm+=+d&inSbkGCWrQPg7%bhffVpF7cw9$s7XLkeiPG}>8Y@2L4bi^#J_Me~!e_ua(zC|nx>wQu8{F4Ax5J2Xq!SMW +z&XF$6!c*Y$80i-9og_rD_evgu7&CcgMdyXv?=@=omV=>Tnxp3 +z4IMZ%-QcXy7Wk{&t!=SW`m)4%8YK#IH{w?skL#;49@p0lKX1a!=mfXI`t52I23|lJ +z%MxH7?WubioQK-pJwX^RicaoH2LrFREug~?D{RifrymIx%>-B47ya{bK +zCj@v1&Qj|42L2#U>8FhA*%F^bIqmlRy^L{xSm6i_ZUAcoY%#B!TDvH +zKKSQj8TvhU?(gMV(U3LLU~DAMl-C?b;hQIHbGbn>mveqHXrkl-;~Iv%`GVkwrOSV4 +z#Ql}i$D%j|-Vl9j^L;o2EitYE*uD&$?aPfHmi81@0soKVmD5TX=%^L}9*0Cz;A~%S +zJRW!$d}mwGhnN*#=t~rzMJ4XecDW$An#H{4&7*mtH@{sx=1yzxaWiY#Xr6R?ZW8m9 +znd8Y$yMtm*&!9I)HM!3R)oxtU&EQjPp +z0RJ>L&&0!nV)FbfyhM0(e9!>wP=yYxL|qo%kcD?<;R}JM6TMK7U*HvJNy|{u0&rHS +z#JHA}?aRQ~zT9}IsC#2a@?lT=9&%_#8{V`&4gU08cXx-}J;*~>@gqX@^Ds@C!JnU$ +zMD5iI?hwE7lHi96uNBK7^GO;;e&?Y72v6I_d!D +zJ=wik__T4Y5Whz`V?4UXOv7B34)d7~F-OUwkmwJfYz&-pV-Z~UKwp1xns{Vz#LY1e +zoO5LwoRzD4RPe*V9pLbvP7K4qlFop0%r?Q{NDiGLFcX~xXQH*2X?xLsSpH(B?UBKA +z1{eZoLbKp(zW~mJN-qzImZvdGTg`ywp#zg>Gag?Zn{d>Du`j$L1o#nn8Te<6N8?`w +z!;_IvKREY;5%5I>7&RVGbQ$gM&1@1PZ1sxsUJ@zPA^0d9^^^n!JmOa!2z=+XN%}5< +zzbff!{y{c2zM;>1wC|^hk#`u^ikCrnC)$$_8P|L-K>G>!vG)*uVNId~-=|I?fOQa; +zA_VREezfH=K>*ut8rOvQ_G{}g>2r4|EA?DE{1_D<24`gp9~;{58VTcCxud8=t?_!* +zPs1oWu%u&|4$_`{-nb@u0RpVT4=b^T_F8FQf9brA0PK+WxS))s?lm5t#D$L!?OEz# +z{{#i?;M`xj!TFYa3jDPBiN=2s20B^={~-czfODhT0_TZ+ +z;z^+rJTpr^={!IG4$B1O#@6=a(1DIR!0D(9oPG+Q8vJms)K+A;#OLHHJeV=;=831B +zo3DX0K+fNU_T;5;?)A&Hi?~55qOaC0d@Ku}$-Kse5BHa-MhY +z4%^xI^UvLW_DJCLzY^n_jXbd#GwAfvS6=Gej>@v|2JmB8BOT}F=|ra);zO{Rg{O}C +zgyQYHjUSez4jt`7mIxYT%DahY)nj>f;<3~|K`#^Z_`jmH%izAz-jNmqS!;1v+o +zd-ZuYNYVU`y=%Q%hxiz`z9=~2QF$7i$29q|fL^)uyv2L(k~xRz9tx$P&qgiRDuseKo2+rkF*8jLZb4oMk@!Bh_yF;tDKUOnT5%s4F&0I +z*T7u1i)hbPRsLQtAfC{C#HIe~h#S>{b%<{;<^A4~w&x9EmEiPKWjyYu&bTI2#`gdz +zbfDrE1fb$pw5Q@xwC6rD3H~OVE7AI!GDEyX(+F@BlV}-^xW3D84He>kFb2-{+qdFk +zDrbAa`-3CS_MVf0^C;MBTm`Taea7RHcWlRx=;!R6+c6{(JPIy@^C;N-0iRGjK#%cw +zMf=b`s%TVy$vXMLpp26!-*|iy^%#!_=!G9{;R9Lxq=(^%lWqhZ$fptD0?dg`wC501 +z4timlDE(Aq4*mygKEK`38Hf#nB%vrhy&Pm$f +zyd!PTNm?}&_SDRkf-J_yb|d>EXoV8nQQ6^t5>S8i5#q+bq=l0wm7oJB;|e%ub@NAp +z0Ja|k=j6@*sBfP>EWtQ?H_f2@cNl`iNC@zI@aj7Q=j5#i=j3e!m&qH}Uy~W)v$xrJ +zd@^>!5hriq$9zKZNm^`N{T$udxE?Pz^qWBybC%AqgZt@+w#^WP5i}swuwVwzHarHN4xaw!7!x@9{%n6PBGcj)bi2R#x117+EHa=}U{3H_O49?Y7_sO7)i>+kLb1k)vvHVM}#~6=QE}iH$g9hfL?+2Gvwe!mR +zR0wc%XVS~F+l|L3Z!tI%YK^$)*TAqiGFn9sr!p9zWXe8ed}i^1J@ZgsT*d3 +zBbK@uoTZ)z=cFFHYsb&-PYX7JVb@VH?;ATEc3na$24|@!!FNh6BI~~y{P;@S_&1m# +zUg}2U@ltof5lg)c&QdpjD+FexThlPG)QjLO^$Ivk-SD3w083py7dR(%r}5}ynWY;* +z2hQpdaJH}db_l>yFZ@^FoYafPtMb~8saxhl0G4_MoTXj^50#eqP2UNQ +zSn5`AmUo38UVPL7Jei9t9)QRQ5S-E0xmbx4q?d2zRU|^}6e-;9;)Gfy2rEWDI +zFLf{cu+r-h7yXB0rEXsdfm!NKaF%)%oTc6X=cH~q6a4SxPwG_vJQ!H&UT~ByF#^s~ +zPk^(1>VJa&Or@joU;0Hbu++=O&?66gOc^(H#7)IGln +z0a)raa8_;uoI_BzmhmI{Iop%J&KP#@2ZdR9H8_W$r&1EE_%DHTj@5&+a^v8v+!Qz~m%nZPRXnJTnB*_?KP~0&oZh!C9dRa1Oy5IESF>p}{|g +zAoWmtuzh?8w$On?(3KY)@s}5tE(-kBsA$ftOv)ha3-1%Z69PdgY#!f+l;Gxw(syf +zolpZibXteF{4NBjK;Uk0`sp#Q{@K0{{NnT7eP2jk@>rI60RC9cp{QPu9fA2E(ijE5 +z*u8L4Do^tSqq?`NnL($_tfDvEXT*Hd)8KrT&cWy5mF*Y7S(7D%Vfb}->I=zBYc|lW +z5>JudM7Nrxq-d`#@W14`JHD8_q=-MDlJkf#GyleY=Zhkm*%X*rN9b?d17c3oTw><< +zL?{Jkv~on_!mI#)IaE~}*YMWfANuQHV270PctZ6Ez~2mR0H?4f_-Ff;N2GndG$VFs +z%@Vi`oR#Q6VE(FdCpdqhx5s$&j0tw=%NQgfcIY=AufzZX@JEaX!6|GQ{@a3L9(V$ryVYzKzI1M$PUKwThd=|+QND5A_4%X61>meuiE$lDwl4!``|^m}sTY@K +zwRO;hZp3kX@X~W9I+KMjX5nk(doFNyOvz2WR9;;e0_8kZ<@i^vaXrU-03QX{8P{_> +z@_OT1!Ak65&BnD-#$PS}l<)nTL6v_i8KLNpHgG=IELjv1ok06B;~MyH5qR9)KP5ZT +zl$kX?%`@)6mt;qpg;$QtJox!2OVcAm7Pp`*y^ji^OEV%|3auU97BQ>K%b +zT=WchnTovZn}L^S$RmWLnd|;?GVkF0uKp6kUJJ%Gt19?g^jR&#AI+;#R@bg&@wy4l +z6ZUOHdnTeKF7q|hEb`oMr==b==b2e+ljkn`YVy)uClAHweFH|b#2uHWMdj#CbEVra +z=3`Z6j_+=D;MC9n&NfmcSWzC6rbY8yAM+W5PZ6K>DfbTyk3BV1n0i6DuJ@@Z~*`d`sXjR#v&3L?c +zbKo4!Q6SHLmf=>*42T$&7dT)l={by>4HXin35a +ze!aiaxK@z75$&IZ08MC5K44sR@4=yUxGWtMe;{)Z;QC-R|7k=TZd?oNQpA9N$@;)!9-9XyBtRc25}M==?zjjN-hx$f$3%R9))Ojh!D%IqqHycvNm +zLc(qE$Arhxo_S3e*QxPEAJ%M=My*6sK=kt-K?VW@jFRw~Xf91C +z*P5)^Y2u=VHrr*`XcMI^bYn}_TsFbf!ew?0iXZe2nxUwmSOZIUVax6kMFqt%!KkE- +zny~B&OZW&x2%0LPdq3yAvph3<)&05db#;E^KIgul_j#Z9c|Xp3&YUD#C{-2c5w}?J +zdc-YJe52~Ga>K`VaD(Bc!NdBm6*sB^`quq`;iUz)sJYi}cdj$r@&^<}ES2F&Z=J>`=|mbfOVxOORC +z@1gc9USG#}XGV7qbQ@XHCQl3Myo6`!p5#wb2bTsxl)N_f)3L^vLWRBAwiBEsAyUg&h?kbeMe)FZ$@OCw-`UYihzW#J3 +zT%!`I)Iiy%c>Oo`+7*9B_qgK6sfH!bz1px&wbL3uH^C94WvN~)f0s*8sw!A&3W~00 +z_F}_J&)=#7SYmkTdCiv_K6ZtuRQ};)>IN3&qXJdH2sXdc@X|#)Rcfp8Nhfb&SL3Je +z@*a2Zd!B@)XH_EWR6Tk?G#FmmQKH(hR#mU<8*Trin~W^YEE$P~?=x+`Q`NN?U82lZ +z`QD=V>B@fVAE<6`R6TTNKKqrQ&mBL`Uobyl1nDnsN;XSi(^N(6s^Dvi?=*buirAy< +zYg9vyE52O$=~Mhjr+b_cepU(7m7@X0k5c_PX!zKGE-U-V%1_+9t0VkD#gCY0?j{E{PMfZT>bp`FJ0>7Fwoyx!BABa1m9O(+W4KH1j +zqB7BAcTeRS6h9cL)JgN9eB`j6b +zV~gQqTd)<6{e~CE5xH0WeO(pv7+!i#kL?7*OV4ROOZiDt?U-wLslHV8T&}}A|L~?v +z35!et={a4XMDg0b)bO!AS8jNzSnp6Om7hIvbEulnO65pzUFsCS9EFpu2{`*(PlYQ3 +zW!=09)9)-DasC6A{mRXB)W^!X=I&TRor)bI&rn^vI7;rN?79t?x;=ATe}Nev5Ef&p +z!0lKka0m7Xd=n=eNcoUwOHeGZ6g2|h!Zv|#qf4M1@gEWX5_tmOL6rj=1^x;L1(xBG +zKmap(Y*^~RItTVRaKeF~Y|Pz;}`IF`*L04%9fX&4Dfl;*Z-Vc>-0aa$uvt-8e`{uT%p&&g~4ed_oNpPq2IM +z!Hg3$z6VPkSm(eV2TlmAK+1m-zK3E5Y8=?+K$ipYCvB5Ff$yV=kobL7b2VJ7ExpzR +zuz&&lK*_a^+@R#|DY*g9ob*gj->*h$meUgZ&#TWu?@7-D_bh&4dY0dWHl6h(Agzx- +zT2J%G&?QfT>t+=8v3~vSaGmiWQ=tH>MAnZSwi;PhnOO)?Mvu5F8RU=lK2I9XN<9O8 +zo=i8tsy*7znkV&>$v@@EM8O#zt>BTX5bIBQZgns8VEH9as_P5%%W35(ynLP|R*GG@ +z_^p$&7FOe#e)4_fUH8KGDLb?hi8OWph_7G$ +zmK7wNquUbJLZM7-3xuc@;>V~bK|Uk}R*%FF2U(y+^ls|zA`i};^4x?Bwv$#lXIWa} +zo?QFGpN +zD;>0*r{ijrvGbk04W0KCe2HWCEgnoB;Co?rD$nu{^yDLba6fho(B=IIv02icUuyjm +z$NDF>wW|n)EaaMn`inNKlFZ1=;;QzHM7ZU&$Aev;ct)h_|H2;WS?Quv=wP9A{laUj +zgvO7^sTh{9IBPeb;kdIWSN;Xg9eZA}kLlqc$rTw;q(PtD=0OU$l2&ce}) +z!~zf2aJiH7KW6=_KLS)AafJVIBL6>}$m#k!i54?8?S~DhkGCec@|=aM#j-Mgp1>_c +z5qe1{>Iq$fsZ)60kT%jvNY~H*&C_W6g0TjLBdrPP52$6Lz}(TwGO-4$V&xJe%Yt5r +zkjVO3bE}c%YSe%ZksFlreX4X3hAGQRewdd7_mZ#9+7gxg4J!GZOcq1t6>QC?yfmy# +z;uXJEwudcp0amcw-68bFHIlB-$3%M|I({=cs;a#ggO*Dc#> +zHZM(D_A)PsQ7s#aYFS}|-Lj<#cFRIMi)xv%wRiA$p+k)CLYa>+3d1~`sNe1FQ3J^} +z60;Mn)F{2r=rT;HFQ*>$O8}9V!epHCKRqY1mItvd(V9c(B19Q)H(z7OsQnpyqiOXs +zlnE4~el&|#VB=`(KAt5e$$(eSEc6!jP83phuN{faeY^&*!zyzs`)r=dzBH=dQg!b> +zfDT%7+j=62^}5iX&dHmdY^CwoH<3yq0?AC0esB4JN>bcNJd(^L=@+3pRg$Q`Og&xe +zkt92lxj&f|55qTxP1H~2i%gV~o!_HO%O)lvx@Vk~ +zkf`63&%&L;=aY~6r3>?v#@^ksd&XJzZQqp~OK$tx#>M2Z-1LSl1H_kS9ln!E5tQ?uC=87Tm!z#1^iY+l^E+qqFwpo6<=h1hd0U1I{1-L$D%`IJvg$AEL}7f!?AL%ktNVV +zGJl2K3D&AwQZL1%^7A=dg=KX$9oD$q+gs>ctgy69!} +zH8DNjttz9wka|?C=C38#OHmb8T|@W!`=_mpQ9iQvbLuTYNL +zw$8oa&Gr_>{V>;7F3qldHVj4S%@}~ +z^?ot3A(YY6fPRtnelfE0Na-T@xL1(<;yLNBCVT5Jv01J4`dLK6C@l9{sqQ|@-W#~5 +zj)L46Pt^aILf`V90cWXd`F$u==AK-Uy|gHo2k +z6za#Cjb`9D#`UpsOO(7LR*o|%a7y=PShuF@x2Vi-580#c3lvVZ?u!aEa($HEeHFl +z7l?(EnYS;=y=-aO6X_e&3Z1Do9viSqWPSS-ncWimV+dukzQ@oZP>5j~%Uytdr7u9v +z3_JC5GsFi=Z8PXe_jR)xMycqh%y8mo+GXlz($nMIx}{pFXr0O3-s3np)2`&wOnVz$ +zcrD%O4b@_`9;afJ$htOt>39O6Yw7C=bO?qwAZHcO47egepRm>qRQ)0_>o1RM4wUznEbrvcAS- +zc~}QOQq?IWUQhWBHBXP2sGLX&Mb?3iPp}KyrI|3w%>TOU?fegm@z2$$s5Zuu10ZKs +zj9h1AS@VGaWu~=emhG$GfvRk~-*#kE`vM2EZLKgTW@-$Lz8aJl9XT;EuTaSiU|8gU +zYVlSzq(&o$GbR1}D954v95k{tq8S0o?kn*)oWe=cZ11h)^opEvNftF=VdqKSql`hn +zoSx;DV-5#o-5hzO%^&V_BXMOenS{Ay%E|B!HfJ6uX!bl3jbd_vUqH;J%VO-9LmzAT +zWrCcRIj0Xfrzo9I`@T6=rhC5!KU}~Z8M{|(JJikRt>##-Q-7-%4{`Rpzs)aP=3BE} +zKfv%@I$vqwHU{XrWC!8?7O!YLbvIgeo$e28YjHhU==&`@c=wA=DfCFQ@)@}MBU7-4 +zb9n*%wZS)^EA=Ha-Xxci=j+lTpE*r*&t7%Y*0@wnx~K&9q*Nz-C&nLx|w!=x`kUg3>GS{esed1O!eYBrt$pff4X+A5GX~6fR<;a9nVr;0^hUbmm)wwkMM`cyT23h@tmaN +zISEsadgQ24j+Si|Qy$4TOV828cj4Pgs6s&CZiEQ#brCn)XxIebHcIOe5ZHte0WHtd +zkLP*HeegX`{xkvtXAmM_(hDNLK$&am3t}%sqY%7rCE*&2UV#VT+fH~N0fBCW2=1;( +z9$%DJY-h<59=U#lz>74>LP&spA#ee{UlQKt-)SOv5h7q2bAf?hS{beejCskr(R*x% +zGbk73;EtE98{BdE2)<-3bT7(B*r2zS=SBJO3zkq9ETt~EI3L~}#3j@P%c%=4qb|6T +z`c7-1w>IBdv*!N|?%2tCT3`VTUWZ?B +z-|GkpR-ZvwaPI+l|B*QUApC;O{Rj#U9Yk2LULkJ2EP#0`E1n;kj%@^Sp +zJVaga*hPc|J#WFgmzet&{DN772nz0f3t_?I)c={-I0(OBWf(!hzCnZqSH2DJzYvo@ +zgI{oEJA#7wze8BCx&z*SC9ds&U$Ei}1O*EYBP^J48Qy(z{to5w7ydR9&29@13sLkQ!X(`LN5K0svFLsH1^Y%KC|Gg?VZq}^;C+RdY{4(M +zy&FNn{a%CxSAPKSeqy&5e!|w!@N$|cwZ2c5|!L%s|3O0O>u;8%_c;6(Je*wSXPzHj6nU@h3 +z%$f@CA!5%6_yxVjLS3$CF44zZKEU?X+GxLkw|%_yzY;7p%SkVZme6-xr>`;LvRd3U*Q#EO`{(BOKWG +zJvstE-S@Q=R2<j*KvE7b)&m{ +K4T4?P%>M$&%h}2R + +delta 165379 +zcmZ^s4P2dN`NyBb4scXdnCLi)3X^R(QDNh4iW3wS6crR5DJmE$<|-K;|LM$Q;$xmJPJS-R +z_suO)Ctl>sd-{?S^A`C&-E!B`*L^FVzV@Uu&+#=p{kM~&WVo&xyW|eJMLWNby}1h}z#` +z&OX`qK~!(cmixYSg0Ii~GR?Q-5a(#;x6WWx^v;F5RXe`B()Z8A!$!UvwTWcMaVj6k +z@EyP7hiCh`{k}qTVX^OAU*(Q_i+xLczRn$wpXd9gFDk9wJhFRH&=g9Lkcl@;8w_=fRV8?5> +z_+CkhI`Z@#Pi*p0PnaEN+~o@`G70zi>P+gleKY3gcl+vheB~bBXlm4@AMUvHC%*Hm +zedFeVL!wSOB*i%WSL35DWfw~qM}3xxyB2HJJi9n5 +zkLU-BqpqgnlA}b7CDTL4%^gR%;qOhzb%J@5DsvZn{@6d>w&VTZ`ae3>G`{0ce&8K{qnVuW +zCqL2tj(^#jbJH9r%DK>~50Wiy4L&Ka120IH{Vwp0;G;W!7aP6eFyD~bw>WwUjgDKS +zo7AIduU?8#Q$c&dspG_jeU0NcQ5QPdriCjPNHJ=*@m`6U;G)Sbg3~8jBPp$Exk*T* +zTBA}Vnen~@^hY~#IlDTbvOlVV1SG?TD|suWAn +zD8+UulFSCy(xoVnqFahyDTd77mPB9R8#Y-<(MwEb5@j;#zNZvwlSrvIyGWt*+@e>C +z?NaQNBGFU?sY~$5Fga +z+3S^JQi_17NG3Pb5H5zK7?Wa7iYl{>wK^#pq-d6+TZ%y`#-*U~VS{+H^>`{Wr6}Oy +zbYHdXZIUA1WSu}&8l`YdE$`Jyu~CXyw+I%Wxv)d*1aCLH$R;>;R(Lty>|>Y7QjAN{ +zX(~=6*ek`b6q8Z}%r@2%rJ#AodmGIJ7k-nFLPft@1jkFlhs-xcT&qlqYAG6|*eFH2 +z6#J#fFuqhW=#XMuifJk4q^LHvT%}%$HYw($NHM!u%aEc#iV`U{N6RCXAVNtk6XFucMH?a73jRd +z$T7Y&vYBF(#_zAABXTpNrZhTKirx2gaO`6=nntyT`Tgm18n0MJD1RBDOf#`8`e<|e +zvgqrn1L*yA9Dg|tdixbJ0{wgqrfq&sY+$*tN-&*>-Ob8{W-G}w&3?X|eD%p*waHpR +zFx%8}Q7lEb6lG@f3aZ&?_OVuIQq!qumttIs6jQ-4U5YxlFwNPXGyj*D#GTdz3qSX}fUYgm!MWz%(QqVby +z;eIL7%^undHnoY{%tcb#PHr;3Q%UZGBFSNO`wW&_J54=!4mY}0QvdsuFKRIKex +zvht|$Wl{<$CX0)7Daxhjkz&rm&0M9+xCNbtc#lplT#QOlU@Ed`ugRoR5gdC$Le?X1 +z8$djpoUe-d6EHWMrlJt=YkcWKu7kV#lY8IG8fS4E#5 +zEPE=vlS#9IYtadWi*_kSq)0P+2nIWU7T&bR_*Rn*^(PmZZV?>*Mfl2e7NT0glo!Iw +zV`eiunUjLLnky&m3169RxK>9$5$yg$csb2%%XZu17IdzqyQ66zBHA|UDo!f@bYj3PUk>w!;}?jJaS=-R6jny+#x*Q5RAxE6*fQq-9T&!7$)l0EuB#hPOh&ZMGG +ziZLmAO_4yipqb5kWo82vq0Y4MX>MO0o+qV;=N%FF@TuYJ?>x=rD-U#}?ST4K;SKzz +zwt&*6dmAY>b5UvBg8G#9vc_`7G}|*dEVr?2D7w97CmmAIT<1Nyc{_`WO;Sv8kz`s3 +z1$)j6pIN@yc2@KXGjmpS3f;#htR?Giw}{$%mN{o_^tHjgXNR|>vk2FwYaJIuW)Bx7 +z#&-mY=`S)3Wee+D9&a|2JGy4OMYGvO +zdr{lhnO~h9eOj>i+J#0%2vTBF3n|4Ck8FL?4J65Qa^xa7ShLW{e60ryqi^LITNJ%y +zRoQ35*BYw}&xda?R~1D+?wd44WPagbefVnqH;3nKw}j^%>&^A&M4!JTeZxYXyK<59 +zAU~fu+Uz|ix+9qQ<%KnDv*Jw4xzvT7-!R`hH~L!NfV)edCKHOIF9@TPn}FBT`sz%NH^Pfuh%WIy6+4hZ6E^A +zHWT8@E#gek1>}pKvv3hG8@Ql5PA>YnNHSab{frcJzsY;eTqI@MhWm?FZ?x-f%Nx{?MopcR^=T)ZYVzRDti(v9A;cK;-4P0wZ3Ob?E +zURKFp!&lxJfsdIz?1V1=mr&6z#f%iKCW|3m+_|7<7+iEpQEfK!-hdSJ;X$f!QJVdJ +z_#8TC!tb7{Bv6qx=EKbK93gd!7xK@>iZwlnC9`1MQ6i@xww+jUW)I65i3_c*oNRm* +zbaT>lOn7;F1YVyMzJ6~o0zWQ1Z#v%P##BTnl(wgaue3WYJfB(-o(If6YEy9M>hN;0 +zNxh7k9CvwmxjzE$y&`=5v8%%K%xlB*hU;B!c3c*nuqyqA@RdgD!}I +z=_kYUCbN&sg8t{i%dIB$3ZCP?4==Zy3X(&KuZNdA-ww}{?K#?Wq;>y2eEqb2;d%eZ +zE_-O~vw0nL=0=Yk6_E1@UEEo2IAx)=Jz->+ee38UCv|xh-F)?)YCcy*^O3%W +zq1|KCPY-X@d%Ah2if(gvW`)-aOu}bq@?@JLDxxM=@3`tS(Kq_&jJWG6N~Hy*oPI%-$WHVy5WbnzNzydaTX| +zpYrgF!Ra3I+mw6yB@2UH4VgagkQ}P_$Tvf7_3#GpZV$f|JpIyzVQvSX@zlQ)ykGdz +z16FMi$~}&@n5=uEm!y6Va;Hb$3Qiv{s9G?-{D4FE&6AMnqbbP=RUY{{vx~5qxhFbM +z+U?O^gz1onzY0F?;ctM`1OGOjX%!1I`731l27u*4kNhFzDzla3P=iNabUb@o=L~rG +zq2T=XOgH8vCp3BFQnP`u +z8Tn3hAYsU(tutFmOT88zWnht!ZArFFGNZB0JXB*@sH>MRYq2WVuKF6mpHpBDrY5BOiVO +zJ6h+Adw3#vVBLX0?wjMx26AJ%+oJ=)8jp4|Z0HKdb$Z+B#4gIyrycQ|MS2z +zP3mT9O^Qdp9CEX%V7c=%3$1G*_nQ`yOJ_Xt7a=EIwb1OV;N@2@L65u# +za)a@0p?k!BkNjur+{51kPdBAo=u4NHYZeCmFXUFUnY;!^J@O&$FJ9I;^i4O*@z*Z2 +zUIMwn>?1kU>yej1PV(>!@MaHR4LWK;40 +zofZD(vL_tR71)^pZ&(=F`4~RvV+{Ey?fvXRJvxQ=*E#X_+f&GK;OQQI6nKrPFqCn# +zM^1%IPb5h$?e)l~Lmu()TyWyOT3L@UbxxIs(@#<;n>F8r-0hLS4c_G8o53C9 +zdyujl^~jGvrZ1{luDQ`!u>AybiK!*IwAmy70&=g1{|Y?*rUl-d-+^bEUF0t0c;we1 +zPkG$^3B1Zv|1aQ!9zG4;?BV|c?-p*>eUC2Bvz|)6REM^8PQbK$k9s7fo_FWBBOzCr +zZ7kP&Cx6h{M7xS=*6XLz=k|^3&CeR`~vXwo9DCQcbAydhiHOb +z0hxaBLc774&n>L=S;+L!hvf#3ya6&jiR>bI&?ARzY?H-uz$1SL@}Q|D`Q$>+k6|8y +z+~DDlnhjKa%?}~ZdgOla!1{$v*#S;pTyiqy9{D$r=?6#Or@1@mk^caB#>3wPkN^C_ +zXcOS{9VodArhDXnLT)nKNDkF_0({hLc$k{g=#g_E*O;v&hrA!-&V^j>xgcB!-sIsG;H@5B1>Wi5*MXM{ +zH+hdlCxp^Gl|GM3Gv7VXTK7#Oc+~?7`PaddIu`Ofz(=+$OUI4Wg&Djj7K9;KNdbmh+g7+b>|cCe2?N!WAKvsl!ArUIWwMf>ta`?&$nM#Xcq)e^6(V!Ob=fHUg+WM +zb&>PFI5&TNZqboD{EtUZ$JCxi28+Y|Da3`~-am!734GLjBtU;UfqcJ7e5rE@_8iBL +zcm1Z~C)E4nu3UbQyx6p`eC{%~o`1+=tsBiYmLGNH%7d)`XeL;WTF%z<4G3Soe1X@CSe=Ju7NxW*>=QjrikV5LZ0@>KQS9f +z_U)G9Ewhy?`%jTjiAP8b+sqWRhvgEIm#P!YC^Dh1%Acacx*yi|TgdEa(Wk-fx0yXK +z%gtbS^G{O7V@0@$xZ7ZS!8ne=d&I3j|J1^Nh}0jI`YWCO4N)!`g^+ZrI4VYSQl!3f +zuGvNT1~-zN>ih}NIdI9^V)n887_4VtjVzoOP3qGmk3pV;+z3BOrh?^jPLtS;M+%RF +z{5jLY@)pQ#kgfCQ%r=(aCV8n-1DpBNiO)>1eER9)JT6{p*fGDzBy6Wa{k#t)!8zR;?I8J@Y>7R0jBx67ce~RRksNvka^n)gmAHR+ +z2Ye_=xIM5B%@KDq;Q1mutHINQ0t&&e0Ute9Ks@~4B|PNVzxykL!Ba5E##P78^FM=^ +zoFEl#JN^US1m1`MC+13`_KyQ?x8#GDr?4NoA8!?Z&ZP^4d441KsB1ufI*I!CfhVU5 +zu>4u@8t@F%p8#(IcP9b2`mj97bQS{jyt}Oi&v0*?9mjU{XTa;gZBK+u>d$FJ?}FR` +z+2+*`J__EBFmHm_yEkHvW3Tp66ps({P2hv5p8;N+CZGxYO5q`ACj=Xy83tu^Q^K2_ +zO163g3w6izqz47eS#A>;c6 +zjp#ok$V<+YFxhmu{dGmbsSDZ#tTBGhjHZ-<`()bAD^a)u$qL)Z(0G4Mq2 +z09o>snE|&m`AqOM^mGd9hro-$?M(g|c%#ed7%hasI}o%sZD&YNvO +zZv;LCo{su%!}yuO;0D=vCCU`fvI|Zoz&EUP@Da3et5PS&SA0>Pj_%L01d9zb& +ziuif%tqlYl;P|s8p;7Q8v2!j2pYb@N-$6b{Q|S)KvydBL_AGckhQN;8SOoq*@GjJk +zgP*iQNz2PG6n?GK>oKT@ftTL}z8&>#yMF<`6THfiZ6EP?{(bdPp{OFs!CNICJdth< +zc%!-GZl8<5yTHp)-;T+f;FTV}=o~lhVy6m13Ib%CeZQo>uOmIdx!5UOB-}QsTkM=B +zm^Hxc1@I~GLGXRxy>z$1o9+ALbEVzeJ^Ui!A!iVRZOG?fu-jvBH~5IB{?p)lJ@sD) +z9|w<@yqr1k8JCCVGd-nPGM$4#3Jk6VPo`TM-fYY62Dg70zFTDH8SrV;r(Jh@7d#Ww +z*zIY4f5dqbI3I!^2D#t`9$s#0chT)J{kUR~irZxGF5_ePh`X2d1DF=;SmgHC;AP+` +z2=$I@7My~-9&$3|#bz@(4+hVdL|Z)xUGB=En<2MBwjK2y@J?_$5kJIs*Iz2Aja!z+VNAr`spq>ZEY~ +z1KtR3>!)5Qi8^$5!<(&N3SPH{@0w||mz-N6Y=pr^S9P36z-PhBd?Ne?+^%Y1`80St +zW~b!|7fC{PnS*S^ck&>_(?yau+oe_D$>6(1c0%Ce-~-@KgLj@Sz|Nu9z~MHJn(+-%oq{A3vQQjs6zdpf#=iQ;LRS!Z-AEx4;{FXnuAd7F-W;Y5^4aC6MxRd +z;2S;l8^GJa?WFq__C++vdknn@gT3H$2pn~p1RkN0<;^Bk3O){QJL(?rX%BxHeAeYhItRWp +zdY=T`L4Jff4h;@(ekq*eFP9wr;FI9R;8Wl>w=aUvg7>4o0q-pr5CDHsc*yC8U;}>$ +zgYDpURxPiTghs*bwV(#vq0Z#Z`nez651!(xbh84U=JJ!~4gLus-Qy_E)c&5HQ=fK) +z#OGPT+pHAMCE)4Qk-XXXUo*SNtacOR43FGn-GL{HwKED{4Bmh%$p^&wj=E`?oE~gH +zCYqKPDZ3M{l#g_7da(bs29qTKqc6 +zA`U!FWQQKT4%3}p1LRD|)@z?BB003Uil6J=2ph*4!Mm>!=fk=lX3gL~bnDyGpySxX +zX9D%d-jIrus2}wi@sn|g^l20LNy0-;d%79-{R8=E(t>FRg&rG0|IcD;9Lw|M=j*7L<;9~X7fwbf%il1gWL~! +z5WJe=@is~q72f^3iLllnNyog2W%!3*K;A@GzM0RiwG;OXE6;C~k$a_S)1 +zIqRp!xU&m90|uvpcX;Yw1>Om6C&lgH!{C|lvlV>K<)QhT%-12*)Jn~I81OG#IU&1V +zP(Ju6;OW;3uxEx#z&kO!F!;_L;CAt#Q8uIa&Q1vHZxBa?QaJwt?*q5buhXdOIia06 +zG^r=u?Tg@c!J$n!RXqycg%;V%)CkQ4*l2MgrSKilzlSw}7{; +z7f_D+kAmA(i|n6={S16?18%1~VXz-URiij6l)^cYhJ;((3BDcmzW{DmI@%j81`mLz +zd_(r_qe~g_KYH2*UfCkto`@$x +z5SpxjQ$ZR{9&WK+dZ`rwD#6q46ktE7+yidcVzTGhUx8PCOX?TH&pz;kP6#tTQBE=& +zUZvB*C3SLntMOdkzDAt$YQ0;kcflY3W|n!{w*}Zawi`SXyc6~R1wI6hfpwP9Tqi#( +zodTTW2Viiv2u^yN06P*ln5;k0rED|FOC9TF{;BPArk3S@xUwB3=fKy(OU!1LFQ6ld +zvrjbQ95I|Pnq4G^`XP5io<>e@gSVkov*7-l#GPGjsvkTPJo|eBGQcaqYrwNH7LCGJ +zIvo#5P5B5yUrWHiu25w=<2R;dFE!^C$jRSF9Qd1a<&cjKYi_MwzzRpX!#`DJ?p>Pd +zM)1)`#a#)~ejGgIF#!SaS0eCP;UOm-2I(+Jy;%a6gI9uo7Q6?%3jAU4IZyqG2t4g` +z@ZZA@ZgHG4II4%x941RnmW_?eT!DFh$EMBj+|H-XEtULnV^jy6M>d|EtI!_jl# +zh1&(#dHpx=cJM;fKkf^X&WJtGy}FJ>ve(*(h;7B&P&Z-LkB5HJXy_eBYi +zG9Vxx{5J4R@UBH7JO*wT7^?>#C+=Qqv!9oW)3H(>+JFEr$o@_koC7}gd*LZkIE~vF-v{p>mWuU$DPIPsRmzsTWIYUy-XMWDy($%x!7nntH|S>uUnO~|bBAd3+KhKw +zVP=;#v-cREf~WmaD$)#cH~KjgxeKlNl0<8V+zt6=@XXf)tj84J4Q>}iD?$AU@T4~c +z#DOP$S^TGgV_2Lr;VT`x8d@Qm`E?jLW8wi5$oZ{FeUtKiAM$p{c7i51N}Tw&#jFzf +zmV(#)S-5Tft>7cz)=w{Z#<l&DBob^SNLn!H{oUe +z$uIq#z+2Ruhg}(Mp-L&J_$%Uk-m*))x$85N7WY+lhcQw0&m+$D?b2^a@UsCtFe|_w +z=Z^^wId(C)YNR~{1G^a9EQaOOTP1*93~mwut^yzRNk!X~P2hHQIGfOqz-4tfI`VN? +zIB!GfTqKUl5#X362|NXE=Sd-WdbHFJAkijpyP{k^_>aNsV+F*s|1$bF2B8UpU9V=* +zZ4%fnI_DZt{Wair(Ya<~yxn5d2UVaLAV}j%x +zhjv^F-ic-Bs>HqXCE+2*E8I`QQs*vIqXLdzf+M?rojsC2AfD>HbD(|=-W~FFNz_~a +zH1PbR*fEW$b#xtsW>;{WMjVpe;C4wo+p+J0`)Sbt-gYC=qc=)myGEX!8D-!}Nm9{0 +zQBr)T9zu3d1bb$E0NgI4x5*9TI4^>yVf{RN?)nROK2E{;sPCuG7JRTZc=(CL_TLAdX+O4=laT7Xhidb`vbpUb1F7;D_!t}w +z!*U$Fcc}#SgD-AIVDL=v%sL2T5E>v{6@hO8FFQ#B*pF@f;C3y;WK7;k;_^T^`lADH +zeTSHdaXR)-XpyY!LWgzY)43SjE_6uq%H6&JZWlVt$4PiAxLxSb&X;PX2o?jsK?a^Lm>w~wVek*v!SzMncHr+Y6+tU!b +zUBPj(!Cwd83vNd#_D(+B??J8kPR}LIiQ1(hGf?9ia0l1Ue&%)b?{*0N5O5-Oo&X;z +zl9n|`iKjQfONxcZOW_ZXp#<#8pw9N$T7djTfpNh#80_kXBT)4 +zcnaKo0N#A1)Xzrv>*O+Ch)j# +zh<`G7w|l@l!BfDu6JP3V#U5Stkk$$Jy8c%>12C{RZJ!ariN9THHo)|5vxo96{Q$CE +z;?tfmQfcaN-|dIlEX>X&zSQ}_f%x`Tw$o%y(PxoW?fmF)`oIlZ02S%S^DMti@>1u= +z2dwSYtK4j6`PVd6mO4)zkVkOTe9r75In?o8$*HMDnlg!si?#@_zC(B%_%Yz!;57B! +zZB+z*33&Q9#ZNQpe?@r6>4h*Wy7M>;y!>?=;7+M%4-P+_*SS;e3a6H5f!h^M?RBRP +zJo_&8L#K0l+PTL%a)o(503P?Pg)Mjwybat2_!KC1Oa-x~wZck8r=MD({ +z5T;@9EO^)5;;0fl<^gdu1D+3_1)lzGsb2-Y4!jvW5r_Wm#NGSejy5qUhruow*d?(nU3UE4`C0wMi=aa4l9v)~Qj +zxbD&8<<0+~IsD5`$;&SH+Jh;c@u2X^hs0d~?#>0T2G0av58eh&Zr$x$;AvgrCkgyv +z;VT`l@C*q{ogJv=ID2tEqgB(VDc{X>rsICJOU>HmKM!t~nw>&_{S(|SHQNlw{{_$J +zmb~ah;BG4)68}5F(H%~;aQg8mgfaxU7Y25DTAR>w;C6Z1CItA0t>3e-V-KerSZ-LH +zho26f=<>tn|8TO(Z1_LwkRL(c1Uq}e{!Iiv4j%sliC->-RKuVZ2Hh~&1fKqcII=z437!GogZj^dkARnf{}nvBm;J1p|E<$fy2^16ZgK^B +zaD#tz+Sx@UOsOaw>(uSQQ)gP#MQ@qgmK0KCEa`9B}GfBtb{7X-T` +za$S^I>;|_>BHOY51Grrh*?zI@P*=I9(0@tbdU4}qgZF^`H +zZdYG!#iV!_+^)WC&kXU8i~o>aSa}AH&Vi78v^2F^@^bD3w<|5%7W9DIm6q)j&_Qs! +z(sCjE{2w@0TBiO-m!9&3WYmkLmPcSv367ySqE;{TP{TVZWO-K!Gg=q06OZ+FtBSc_rlRP%`VEf^m&q(I?qco^jd{? +zz8^_mtypI{8T=^XOPyT@>hF({x0jmK5BY8cW<4IW9&o#Ca}Bb172Gb{JR1;qi|8W= +z_i|FJG-GG1@GNkb|L3Z82l8x=@AK#g8IJ$?*vaoLcTsp +z$S(C<2%ZTpOFh&4Y(s~XL1_A!1hBjw+%EpS3H3LDxBgn{Tiy+BSA(|vIq>!oRiDpK +zZ$hx^LtBH7!R`9cmM8v1T4vXWw)|9ZyFRq#=Y!kzp>4yiCGK7yut2oaiI#m826lbu +z-QeE?kBgScFbMujaJyji)L}9PH0xjuz~lO$k0 +z#y1i7!3y6Vdq} +zjSr!I_G#j1Kk9!BZdbT&29KqW{(M;WV&!Z5=`V{o|K2u~^4?``RW!i47zTDJZ0qPV +z;03EB@GJt{3!c4NICX%#b%9TUXM&Fs=fEXW-8}j4=tF{sKP|9IpktHCHhca}4>7K@ +za&)Qd#mX%^eE*3)Iysc%oK|*jc22Go*;1^QBF`;yGo{E9m@j*)WN(e^i9xQI=fX~W +z=1PQI*oi@&_{>|q(zVYMZ+Q|TPu%2*VV=0j%QMd(6H^3YebKa-=b$f3VXatqg4PNwTDCkqDoaN|17$r5i_ +z;wDSnWQm(BvCo2ip83;~m}5`K68lwRu}UmfiN&fMb7WFX88W3md*?J(i+#34%9b>; +z#XMWgv&B3o%X}v(Ce=KX6mw)q6k6VaedM5mWF$kKlOs*YkuW)umkf1Iu7t@I^IUNz +zgPSA6nIprQlPl@viZdC%oZP&V+_*BxIWo98dE!O}HzzO0+!&0>M56f;iT)mu^QE;3 +z+(Pormkecab7XLH)`)?Oe~yfQ4th=oK39f1SB5$_(`{g`jB#$J>pFK;*7Y1ISB4{3 +zh9g&oBXd_U5j3MotrP2%Gl@TOTsb*a^*P7&6gIg5#MXF%-C@;$C>{f7jtYvt{m8TGQN44 +ztIXQun1{3Fm|iVM`08x8(&`+y7gx)ir#+r#RB%KpvP}H(F*k=~OmZY-j)csS^Gps7 +zdkL8m`TscAH$_XM@P7t|SH;aWFEV*(d +z<;ua5D~FElZ&Z{%kz*xS4w76sNb)4JJellyGTHMa&%DgM9knOKBsZ8(?~OUZJaBK! +z&E^~T#sqg9e_zb=CmimNlS|DxRQ!9#|NSH;&lgOlkgG3TR%SnuQ_2py}v5|W5PoYJJQ0=6T=$}Md0x%^Ysr?-Ik(wmEswS +zSI3%%pNTn?{uj<&&%`V#ZG==p9)FIz4tndffqPT!0l$FiJge$&r)7js4mOOI_^pI>nn5ze({P#kHS7;nKA?DuY>Npn2a(^MN&=R{T9RcCy%>G(hv_ +zw0S>&jlo?sqn-tVRN~jbGI@Uv6?zV2N8sIx>qPq%|AK8W#~)FG&eXqrKCtH1it7ON +z5qO8<>ug|hy`T8e9D-ZcpalAlTL*Y*tYGorDKHs<$EVNN*Y1)P*ZH<9uIqOTKX_{F +zjbJdYxDMc)96q5q#dUqV=FSCV_U%RH+MmZ98frz|5|=qnuefxkl#d$KcMU7&V>T(? +ztGKQ|p!kHsO!d3L~+@rWr3H2+k>yIk_ +zu&Pftls9^7RsHp +zRC2e;V!21j&ntPmsbzUU$%9HBGMiZ*R`M<-kC|O0myRp>S4y@^%J76aPxZ$P>hpxr +z+;38!k6Ch7d^R^*ei-{}tE8eL1F2(I~G3@Tw +zikIXNppE%6iq|PVBwVh_4N7=H8T2UrGsQ<0|DEEqiX(uVNLsF2xC#AU)i2M*T>)qM +zq7vGa!7GaQMc~5`_zbvrT=#>Qar^}Xn>U~7A5`GD2s}9gx9hub!(LN<_Nw~a(`Y~a +zq9}hpF#j)icFR^=56$ifJZa6mpE2c!m(Ami6HCa>u8xsjmz%qO6|*=rf;wJXUZ9OP=I^N7>ejmWpd6YNw_hS~&0fXz +zXbcON`yVZgMlkT7Js)_xN+?b7Hx$oSTz6uX;(v)fOq}v-wb}Y>IxEye=M(To)oHs6 +zxsr6qKUAE`qIqur&WXuf1RlpdO4|kWPha}ug`2$HF$tkwRN_KA4V=rSl7t@VM8z*v +z$(5WpUtjZfZXIo2{{zBhR4SCC(Fg`5rSp#VsrpqB`1%OEP4SQQsC1f&-_WRZLFY7d +zuZ@Cx&oX1+-mAxyit`JV?~LLfDek|}ZJ*qs>idv@2yPGlTp7fHb6{OR8=Mo>_dofn +zzUDm(c*xDded&X6(9kKa=jTr4NGCJ}&I$cnHGmg~;*A?{fb-6*3UH$`@UsWnIH5l& +z9ss|9xIU2LOx6oDqDc|VlEJyqmxmN^?}(-=KYHW}6xZjA8sRdXC8z}hxcr~G2BEuTeV1M;3SOp_P<8q0oPM39re9atRMof0{8l<79MhsAswJT +zg2DO-0h%Jz-x#5O>w@~Xa9d?-i(tTOR`KR-L05$O)fG~ok7<1xt}&@E(no+c$UNZs +znoIvFI?16v$UGjuQJ2fuIe`^t`EaT;fvkoXh#Dk>m|x-5O&<07gTfXe?7`^PEm2jRh-ilPpYJf +zv~h1{DV_$-?a(|!_+odsPFDtPg7#dVweBk&<`4n4HUT=GiHF=pc{F>%3B2poGzO@eW=^%WY6 +zN#$>iia!nRJ%VObeSNK)Rs4L_C3E23Q*zuow{J||NK8U$qU^YTgYkQnV+uHr%h@Wq +zVsLKki>iK^**p@n#I%pZ1VUaLUOkLA=6dYA71tfTI|83lTu(0hLoxPGeE#+zsfxoM +zJR373@DXrs+^}lgUU2V-jDqt3&)26~V-UPuKMl^AZcszz{|o`znA=}-@qVExdX>KW +zDmDpJ1j{1SDwkT7Zmq1U2({|Kxp6P6#xXx7yHAtsREZ9Dx91ZhG0Kk~BYJ<4-3t++#S%2mW^<5vAa$?0Yv +z$%kh`X6rwgPdM26Kg7g^3c|xUJNCvT1iK;_ +z)5Fuf^wh5(GUxtB1v0O0SuVsr${wKhjxhzv8+FXWg+m +zd=4^a@tXMwn~kxV|7rrXxjn103mD&PbaG3C?Cs#R2s}FiFHl@JszLDu9WVUEgASzu +z7;y7P7MX`%qqFqzYcX+$4=Uje^AaU*=9mwIa|1`rC(JWmC%#wlH_WN86R##-Is@)) +zaa=Wb)4|7fqT;$`*=8I04CX`T@NcR9Ei@A>7b|&8$z>*Cl;m>dTz5~EDI$4owX%L& +zS=U4`YXV2--9Ad4*EdSDpjiojR*u@t9*T2#yNWYn-X>(?-k`&8FhZPR#dV+TRa`e` +zE&`8tKO!A`C?pAAdC=_0hXFTmT(zUX?0SQe9(;qo6Y&nLU1ZUFZ&m_d-g~nKS}}%> +zj7G>juoEiOMsRPKUT_X`L4aPc^{FtLPl9t(-ckOigqt02#w3{jH^Ve&CW6N~iO(Xgoz=^dDHiP4hbNc1)bfpcmgpvyFgnlc}I0 +z*rv?%t?7Vk=G$pfx$>~s>~(FHk43Pt|4}+;K1FxnZ_~MhLk8n&Bxmk|Db)pursz*} +zj!K5iP0~4}DPE?IhXQcKx&2QRC;3klryPPe4xI}r&Ji`r->j#JbOvyF>vQ^7?6t@S}U6xNb2+PpT!;GDzzi_E>_l*7((?iL7~!}}_SD%W4I +zI)cA;lQ2P1J0yorQ^b4Sl0#1fn_iW}%p!C9gw0_<5$FiBDAzmVtP>uJ3VDjFq+rU*70!8wOn8r?~oLn{Q%VRjL{ +zV54U@-13eH{(6k>FC_OW>#r&6A(O@OFl3JUA0>~`k`^?&lge7l)8GenWSu0(?*2=o +z`xhSFzi>xF;70sc#i=y=C{Cyfve#d|;`OoOn_maO`8uMX8|?(=i=yVU%FnR!C#vCfv~~qu!0J^TeR{TQ +z6LSN9pb~CS@ilKX8^~R-O{L-Z$rc;^=kg?nx>Yh-?v0Q|ocyB3?S&eZML9TUr|(HB +z!M*n+4Z=@!FYnr*8wT8M^f7kr6m{GBDeAU92;6Nx)sXG9Y6Z1(0J3+!%+RV8bg1p8 +zr7x)Pn|)NQjk`&Dfqg|OUy0yeC*}20pOfZ2Q{GG;f1agT-9tHPiG4(l)DOWaMK;H9f +z^DXk8>tCn%#`WQOt8jS+sSWbKFmIp(Y*$>@-yMNZg7f5B7Arpabqbs(*Rt5qys+_$ +z@?L~_KHebjxn(+`jt%o%C)Dxfd9Lf{H_r0|^*O#>HrtzNH4MB7ZBmZvR9E+Ybv}R& +zoObIxKMloeTwVmPYaiipIVrWV31GCNKkVMz9DhAIftqPs>Ez1IaCgr +zo1^6_aBp+$qUPM$`WK=#sL!3Md7}z{m`_zth +z$lio@n$0BB-EJ@d!34w^Iz-xKEDooBzE}=emr4QVy9AIEN!tw)v*w +zpWK&_y*U(`7Lw^vYbqCIW*ZlkuFaKI5p4W8mf2UcI^YYN3DCw|9~L{CnM%&|O~DB> +zlylh(<-EI@u{=!E-xLg+4KtMUNVBWD{`9q$p3Ra>J(abOib=DF_SR0LGPgfYwSOjp +zll|b_kqLft#6C)@U>_yrv=E_<9VIA7^y_a57m9=I?Z|A!^&GDRKj;t#_a4fP%FpKm +zZYJ(a{vB>1-$-s!y}t3AQpwxvbKu-S-MP*tsn7g(>Ld{`6(3MP#zW@jYnhkdYLRxaBuxg;l}KbNubZasUK386w=}WRFs$s+FM?xJnBQG9GqKv +z44p3aQ%f^Gq?Xn|;FcbvT3YY=3$BmgFWt0IxM0S&IDI*y6P0zo*+%l(Ldfh~%O&96 +z{;O8*lKkfV4=Ky!k0{Fq<;X50!Eu{R(ML2M%@O>KD6YRU+zZa*^pyZRl5G^6`(5)n +z<>&QSTbs&O_q}=kqnPL`^mmVb5f1usL;#!voTnV6fL}oTSk;fTF8;@S(uU0ab#}mw +z>AsYhT9QLmkV^<2r>yHDnAL-Ov)H8Se^F)Et+@UX!m#j_ZZp3cn9pl33^;)1Qzmtm +znllZVTdP0K>^Bu8m(D>h@yO2I3=Tf?_`%s-vTA<7Y$JE3e-_`a=`Z#ZU9B`txzs(AA{QeeS{BySXDnA^?Bel&rp7DRrNa*Zw%Zb!T7aH34VIkck|1+;X|oJ) +z&Q5nrCb+k|c+pJW*w1aMyZRN^!!#&d#!vtLds-Rj?((;}{@nn2;v|7zM6yma8Qhy_ +zn)37Yz?tHdU+w=M!;bWLWGF|P7nlumG#-VJc|7!E`mzXSHQ;>co~XvJ-s~ZFM>Ig@ +zemsMoP0z&~vrNzXwC|8W8=I#n^K_H-2_5;FpTq=WV7vAck8Sn6uBqFF`qvjFW;5BA +zmfa^ZwNx5rP +zX4+kw;@Vxi*~acVlsmhy2{)=!nQ3=jifea{N%)k`@5$|KEO*Y!RCe^M2a@UO&K@q} +z%?2)#?)SwmS)ROEOt@S1eM>7ik8nEOp?%7CXrIy@K_>(rpL7+Yo81L_BDl-EKa13Y +zEfS1vPgb@i_t%nIcK^J(QmK{qZ;oA3TBX!el-daHofjJw*Im_o|2~SHi +zYD_uR!6p^g!KU0nnO5HPpzL>J%_>#LN_;?u(mN>0itAV@#UhF +zX?MelYj?b6EN|Sk`bTYr;C#TYQvNH2n;rhxgkZHY*7rjj%>?CG+6g;uPKVACJ)1m|HVh+Sgh1F;A0JWdG29&@1{mrNLQ +zPwBr_tXBLk)tI`6=7Z(<&F$pR^aWz$f=v*(*K*WEX*PQ(iBKzKj-#)sI~9LV&HEw6 +z-&K4R+}oLB;NH$m>T>gyCsYgmpi~6+oS}bYU!u6~{W5TGfNHbrkXZhfw&GAK)|-92 +z*JxU3Z+VmQr5n8woJTC5z8gA}Icln(+==7`T35@u1)yCA8dGGW!^Zjo(lbn>py51h`>h` +z*HdQ-ToOIZjpe@VH~ZqKzh(jYm+T9jM8P>Y80<>k-tQ-70`ibkyu2**9i3a4}_kM^Z84+AQB6!6v<1 +z8plZ$(O1hyQfI9{k~<3m=TM}wEi{|SZLk=!cd#1FE{@u0YPo1O`?zRzZ9;7kY<4QH +zJ8~=npNqiLw>s{|IsHZr)JEa*cPi_ZFle^LQ+m5iQ34giW`g(jnhmtKd{jBpojeB4 +z9aii&CnQjZl_gMzO+(-gD^?x0-}RR@8^Pb4@^_vxb4=D^$|hj;aBlIYmiB^)kGc(X +z4`iKGlG#eNOw!`mI8#6`zH~9m6tnCIX8EoeJ@t1(m55Eb*i=Tasgh8Eqim=;FAU+Ty-WE3+d5^Md~|dC$FlzTf=vDC+HL3LT7xz>dyW-Iin$ +z5-CnHY9hIhdyNZ*p;*|K!C5bjpfr?Y2;?Q47P@G_y@~7j_O##XD3&#m+wXfay +zj;5m1waMy^U^A$Ayvl9Z6tS;Sx43dr)zU3U?2(@07T>R|^A*?M#x#L*&zAbl%STg- +z=Z>bHZH2%+Tk035{7RpakD;?b-~+gL^Mx!{D5+zLtzcs6Q!OE^gXj +zDuTfrI5$vV|DDGrQEs2+esE4m-~9#@U+@?2ai(YqjZ3`Q!$q>$z(tzzCDGX&#aG1LNVlfuoCV`CFSQ>er()K6IFl(GJ* +z%jp#_d=TibwEWvlrd&}$I-3Ttdd`k +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 +zIt;j{^#8h&0nY8vj(m9>^@z_~fqD!V$xbu-s1 +zu3OUu&aJsih3^(_PQQSjmy}%)8+UjQYH~a7G8bP!hr>qVp?>9AXELJrf&VIyY)2K> +z8ICKiGn`ReKW-|2o1D?#{71w_9g-gCys{mCn;32qMCe(k&h8%NKUuihQ5u_2nubc=J}n0KUgk=``B>4n3gsr@LTXbLWNuTN +zidn6~=sS`c#q}}YtoZL#kGCp*xtcjW!sUO1IZp|_FyMSO_m2~xjobZu6`*9Csc=2V +zE5}{z*4J~qUGXzxYorptc8<$??!Z@6fG%(jtQ~cObE5xG*ZIIzUX}U(j-p%@N2W-j +zP?^G{7L6$?DpH&Eb|Yh2+GrzV`mx3C +zQZYqEg@zj?6&ki!*kb*j=bi`7n=^Co>m`Hl=Q+=x&pF@o{oe1r+)Mva<2s9XX1QCh +zl55t%t7P+@G=oZgC#0TsN3W92d)CaFr!nciE8{L;LkqC8jwQFZR@UyanKf-6qRZF# +zi8-}lW=&3W;voU@@LB!u`ZEihRpfxPiag_*{vM>y_uPH2RyMcQT9KjHJhc*fmbyK! +z78%NsKx8=Y)sYNUu(N;~cTk2G)S6lA=tmv$rf4yznvk647DVOF+6qn?+QC^xr*Tbx +zFVc5;?#{njWT?DaWau?dm4Tl9?!eU|!ypof47Xk#$uI&t3m9`pWq853nYE4q)FGcx +zD(2J-lG8kgsFYzIoH8tevx;Ton*L)*zv8*O?HZAx_nPdSOV-U(WuWIK_{R|;>wm;i +z9(I)6e@&!IF6^vG-gRClx)hpO3mZh(5_g%HQ)On>YG|%NRO(U*PFYMbA4d8K&)r$C5gAHfBQi{zr^-OjS$FMgM22}J5E*WK +zjob`k0ZV4rJ$)`IKkTuLaV%`bxbErnUw02lx`GWeYu&@BTR!>vwIW;2FMN0{mgYR; +z`-M}sd~jA>WL&F0hN_F<&#Fs2_n%710p&J8>;0^}W#YAZ`{cDEYqc4)($AuiTDPlS +zWUWUcU0wCj>S}_Wg|xT>GQ6M_X-5#f!`&n1R2P!d+=Hl;sTZ6w^@FpDLF3x>KO_B+ +z=kBcQbah=PGK`w1%0SO?ckOi|!z2>u>bfqHVFq>JBxCK4Zu?o)rq5bVtOTnl`g$rFj-nsm~lZ^;rOC6-&mo-7jZ_^vj;R=ea=Z?wnf_yV;9TTXd*zLMrWGFSWCa1X^ +zQ7Jx?W@$yk2BzFi)+7o=xtk6uP?w31rjw?)8xj?Xa_e +zPPg}sB14y%wT?;D(d(`ibE+T7X&yvW$}j{@8AiZa#h7tT|8=Av_uPH&jUvP98%2gG +z^Hdq=DWB@wC^F0;fyi)PV?~l}9hBh(D`wU@rclSaJ1pkZCX&;f^(*n0M|`GD +zf>VZEa8^-iT+<&#`YO-e`8S9Rl{d(yP;H(n!%_G08)Q>x6`ra?WKKvYI4kKkuGW_74{mBpMCaw?*4d#yv#UYPTIya+8A0)aV +z8EVZ_E1_q-JJ2LDG@99V;9Hv_8Cqax0rD5&GQ6PO%vVVCS=1qaA};1skC`<&&3%YU +z8T!E~!yq`T7&d-|#QzS`k9h8GJ0LRj9uOJE%~LC(r<^elhz!$aHW}_e5XmqHI}2EF +zd)_26ESmWWi9UxqK{r +zHe_a#?XKo%^^C&K0_4N)Wq84anYE4u)G_V$+$=K8nz<%2&m$^V&jL7QSORAiE5sUk` +zrS5>3Q{`sXpgcre~ZYl`4*9($vm|ZdbYT|ZxtEZ +zkU-8X7r!--kzoM|M27dZL^3SH&H`55F&Um(GqcvQj5;=v^%vk- +zzY#}yXf^cDF&=Lgx!}|#-*f*5Nvx~L253RQlza4V(|h!96CKLTpqYP(iYnaEw}}o_ +zNF+LZSH|tQM_&s&^T|7z|5}zq1JbS_y1cbn%&Ar+r@0+bxg0vc*>)E=tLQPVUH=;C +zdp&pG`)gSatA8yr449|NK+hq!=j|fH2omV^*4rZ)#$jgxlkT7lFPJj3*0G8@X5C>i +zr{cJ^nBRH#THm>O(L;4oa-KTF6*(Prh+1kxhE1{=+oS_uDyBi5)^*nk@w0inrX94o% +zVz-J6gJ#w`)=|fZJ1FMV7?RUGfvA*W5}YzjgR_cRW!wa%jC9FKOjt$h2>yC;!m2YNEPIHm*cnd8C +zrwpawtfJhwrhfwID?E3XwuualZ6ZUpd1@u}l(%HJi465fATr$57Rk^AI}2!W56SR? +zRx@iIo2aA1?KvnibRjv-J&4NH&t&|{t|13mlP;dYT>00~5f``RNJhGAy`@;1eHiVS0B);f}?L*Aw+=F~Kj(>#l) +zlwl5>GAw|ziY4Qk{xqat_S}8(og%~RJ4J>y^Hdq=x#1p@LU$(~6)q1u0sr}(kqkMo +zvw%Ez?ca(F`DWHSa!^OHJ0#{*shKr7&E<$n87jajLlroys4=eT&qVrK&)r}CR%9rA +zm&njyo>~b#o7`pZ5*b>MKvu)m?}}t-hn)pch_`?46Pj^!<2cd4D_6F_jHI1b4VaEe5xaoVG(u~u7R!5g`T@lzguLOe7DF@ +zVxB4kJ>?68q|n_JNFXvi`tC@EYS>vot-I{+M20#uYaRKhqtP7{bE+B1X>LVSu7);n +z%FqGMD!Pno`U0fy_T2sM??i^2_lOLA=BYB!bHMF;kH|2D1R}#F?}=m>g`EY+7cnEP=C%72}%zT%=$1++Er!GBkFI3>)UDGSE{# +zkET;(NUjN&hi#E}bw)De!Oj8--9s|GpvcTxM-l3fH*39DWGFYYCa1X)Q7JQLn2cvlGEIds9X*m;B31KoK^G~*RC%@`d-gn>X0ml!9ya$fO)D6^c-?WrO@3Y +zNFXwN_fRCmIP5GyzVQA1BEyuKwT?2>A#ctSb7~&RXyFCsf<7~A9Tli!&^;#R)G(6MJc_84VGNuyOn|eBDdU>{B}hN*xx4Ll +zk)ii?kzvj}RR(%4xFffV3`BE#+v +zMl#gH&I065!ew|tlbN-SD%8>H?h$jU9m#3#L{zSZE^x}w1I{Y?jBEPKkiOq@cUF(c +zP}(Ch44J3OK+h3(ZI8$>h6EzRjXjYJld!XZX?H}17tEMh>!?N@^X?%rrxuZ%=4C{s +z3@hN2VGW#BY#7({mm~eA=kBHtWuJ1vD`7~ki>EwP4Gze4hd(50nL@*?hrM~%&g_qAgg@5xtLScNKSJtqEd}IaH`P&&MKOWYx*mZzS(p4#XDqC%-$i3 +zqRl*226}e5$E48RT}U8{;?H+PGW5dE0_4L#J}fc}m|5$nMIFQLkeE}WNKW%OqEdzl +zaLOlGPRkU(U(x;J|LV;y!DuxVTi +zxCR9z9v2`F<#pilr5%zkm1kzHhUP-!@zz-cPF+gCSyq{GO@A%YmwWE6xl?p$y;F3l +zGEc39o;B{CJ4Kf|BoJLbb!W6Z8ewMv&F(Q7UeID@t)m`ww7b1`i42`cPIEV+a(VQC +zQ-(fpRxw~)(_e@5gPyxj-z73k-X$`On5W7>Px&icDRlP)5{L|s-WAC(4Lb{vPt(6! +zWSBFv*3p1E7TrNHro_I<)P`{fb?0OyWia{GUW7$47uj1 +zGSD;M?dua6ip*?#<|TcR45hHMfO2<_3@@lKv)0jwI;!1KF{f&goaTB&r3?+=l%WZn +zRkRq_^fw@VtLN_0dqjrDdqjo~^Hdq=+2s!1BQo?LfvkqR?ulgRhn)osx`$+V!H}7? +zjwaMG>h^p@WEe+snkNyJGE9L}h8b{HF=t%UA3*wf&)wZ05gA55A~GzQr^-Oj6?aSu +z-MxkcBEy3piDcM>odsmMeIFGWl7E!2^3Xb(QAeITAm&t|nKe1h#m3_;vILwml!3E~ +z3gepoW~8t5-2MEcBE#lKMTQ#l)Jo`C=l1rC3=K#iGF;pr$q)O+w~99WY&hqI;Ss&*NAa_jgB8dGHSdw;yF+FIND4r +zn#l!k!%Lg_o~P2+h#XL41GG&JC^oKz^3yF!k>D02u0R~}O2ny3rhL`? +zYda<3?snOy$?7~vOZvxX2A1?Z!0@ +zc`xGpC@DsJ%!D|p#5)maHW+s74D(1p|3z@_BumD%0UkJ6fAJNB1IOk+X@*$3I^!zc +z-=ffZlc4Ua3mrCqPmlP+iGOmf=g~ZjyH8FXO@i=ik;&dQRgYooUL_=eS +zK&{}M%Pu5%HxhJ%b832xYXjn+N_Ve6`eERJ0psyp4k7{9#1J^+j39pS&y_zWgrQA7 +zsrZxfov2(i6A1Ws=x`F8iDnRw{&V2;pEr&MUzAp50SVrN#EakzwCwhNQg-y!40+a$ +z&y!BGX%$UTa+IW`KbvF<2@WB_3=)vfBhL26M_ndWESVveblG^^S@}s` +zYA>m~e<=IxTc}_y>{PH7oC>xZkMr~xj}??Z8XS_9(}!@>s~?}6rUGB^lPkS^N*FN5h#Er%^F?kE({0#B?z;|2=jKRRf%ixO$ +zRFf47eE_`IxEA_86xs)#+Tyx$2hE@zaKJG5_5kr2F^M)Y@e24|n6jKxfPQ>GUbt4YvtJfVE +zk@*_HFwWNq`2S$OCJ>GvojYk<+a#ZX{|B(_WS!iYxgO*KG`sXcF>JVlc$Bm--Hr5#x>CG@XrP3$AuOe*ZAB1Z;<~f +zhJgc0jK^DC6Zm(sC4fCzz`vdC?)qoBbgqVd2=-+(GHP5E73{*3rJ +z;H92>d23)eio`t`_-qEAb4Ez~b;KzLe>MuLIwKVZyaEGiFyKNAs5KsUJf4A<b`&w4_hFKWc**y4< +zpu{RT{nw0Zp^qZ*x^XR(y!@&51V@j;RSc*SgFdd1|L(xHP-na*;*G{N4qp^#0skH1 +zcNv#LU$x_PmTog>rMv+?Xr3{&90!XnCb*M2$soR=4!v$GKin|_pl{}{ts +z$lXN}B1Q86%zR=sWIS$v3jSy(v1D9jxf8Oi8dq72`#ZGj2=u=)AzP24eBYl2;!~4i +zciF#5?M-G@Ir+tEUEr@r`{Ur(fv+RYU8py=z^B)G$@4w;ry)qN$@9lsXmPa1L$}b3CQOV=y7Zz3*g(A#@3vyuKfL!D83Mn*x +z+{KV_J$`vH)P^`*zeDG~EG*zppo0+`pevVr6oIPTMfb}p=3%@7Gp{<L!q0IpkHb4vFfJx)=5i^AZPn;}+ +z>@f|_ICF^q#L3%dZ22HN7&u_jc$|0{2|kIASHKx(4e_`AHU9<-9I$CTPF%J3#4D;f +z1Me`dQ}Z%RL8tJGR4p}p3LSLW0G$Hz9(U}U+2agr{x6^_L={zu7@Tp+!GD(>;?#g!e1CX$!jOZ`yTR8{ +z&?xxbn5YHtY{W?xhsNk%QjF)+Ls-$J?w)VSRbYjU(-lN>l{+ftebordvV@C+krlqzX|gI +z_#T8SdUoiF3##0>&hRjrs&EJXQ<|zavo=MuEC4a@t3y;aRgb8jMbri#wHZ-qmKRVo +zYFmb=9fvOVCkO@|AEJ{UO3OW?fHTmxr8xh0`c`WGA5#WJ!jmE^BBgD#U` +zkiQc{AYSvgf!~K?wG*5tpe1k?w5(kF*Av7av9GS$06jsFuOZM=ad@m7*Ekp8aN0l| +z@|@=cg;FoXfP5HkM`wk`wIBwnf`2pot26kI9?$*!H$FF1G=e~F;FPZZuY&(6@NYF9 +z7dm5H=l-9!=UzUqtkj-;)I^5D(vW~}TUiF@%duS-1%JNm+5^sukD)ED{d2&q8FVgr +z%WTfLc1E6eaY)Rgpb~tCa>iAOe-S0T{_;OfW>6*6u=Qv`pwB?+Ht=fjPH-LtL*OVh +zl^8XHcFcFgj2YLC$*1AZ#W(|h^7`j_h2k}_nfe8ISuVLrH{xVuwoFBtbD{LdGJ_W$C( +zuC0wi{$ew0o8+Y!#y3t?fv;zWJgwk-A!fz6R`&&;*B?x)X3)fDNJm>oAf6FR%0nMN +zM&dH#n&3V(R&HG5lUJ78!qs)c1ocS3O-QbEzn^{1buEbZZLHIF4C5Zy2Yw&w9RmM9 +z_elwzx*z5lGiy6vL_4#_wH@*~grn|D8T?n^|A5bXy@Zs%PJ)4fk}nLp+kmux4mfYU +zlo{6s#@r1*kp9NdMky~FpZ(qc{vdl#idSi! +z=A<(oLgJgi^3A%HD|eTmGR4nU*);Kn?^$u0{xd?d@@x21{ORI +zliY4x=Yw(j;mE^FO$|LXFmAk?M}(0adudb3{aXGn!2Pa4;~jt%61v(Q}QTIl83`SQ~q +zd1lZ`FVA-8{W$yVSMeEm9Ri*QMOqM$mnW@=_e8dPP~xT7Xs6k=(Fru#ZCo2A?=c=X +z+6&G``@zrk_4?D&JPc=IDXxL@O;w4CaBPt0X5iJ}eCepJ!mhEkj__fV*k_Z +zvkPe7g#B^%>YvIRB>&*vEB~ajFl{9-3DZNltBvbI=PS@P##IdRHsd-w|Bl&dH?Ff| +z{3-HlBGF-n^n!FR|5;SmAk3_5+<08qgz>npdE;?i3&v5GU*C&nh!2#Kmj!fZZSirjM2j8I(5>F!WBoa@a;_h0^KKo5PE|w9G +z4Q?PFU;E9omn^jr@*?9Z;7Yc;`ho1TuVj4PAl*QD6VU)ASxX#P{NZ$*71zvXPM;iJMg42JYM +zTy^AqqgC)$tcMNoiX_hMiOR6Bc;Q+EegRHNRqn{oMZg*}>-^p(|7|@QFzneF)|kP+ +z3H~>u-j)pht)5?>enQQ9yAkMDxX(3gTxaykleWr~n{Y@#KI{9NM>w{>h+*t|3I6PR +zIfMTS{Mq-K=lc_}u}(YO|D1JYGBgVVpoxE>ii +z!aBiUiItYP)Gi%#0Ppj4UK*5rE;{Qqt{ogjp?%;iXwbMeK>y(_uKjbsh#BGz#*u(Z +zOn@`a^i~3iPybnP_4oRV)0`RN#4AYfO?145K;#>U!;{D+I4&ojpD3;hQuEKcO2K)S +zsC5T_Ay+JQ?w)1&r_mkO|7&(f<^K+}U<~KK)p-0YqRqHo8}J&t!?;fKG@9;lmr1sL +zy-33z`!MW3FswgaYr&A2burL9k}f_qil{7p0h~|q$}S7S{WlhMGx)_=yKNcxfam_r +zW_;_&pbgM^$%hb#Zz&lD#}p?snG;DHJZ-AS3N&9ed?KUFMn9xobz31UiJ!~Ut9b(S}b=*#kHW)%-R*r +z)$TDh*O)mz_G;bU75P)zI*jH#)MJ?ZDebKf%Uda_d%xMWs2LPB;ENhYSei%EMeQ3y +zbV@yrsQ-zm6F%w`qS8F$qt0fCI)|wLg{bpB>LQ}jEZ>G90`6PM5Ooz%{~J-)eAEp@ +zr8(g)`?X9h^UZ>GzPd*LeJFsm~pjVX1yIYcU))jBKAyiqRgE +z;3tDmgL4y~F&;lDTl3ssBeR{-%fno7%dO48yTHeAp!R_u0UrW?I^Xy@2E#MZ*%bJ> +z;B&@xmggY&JUHK6v}nAB{wm873>>g*TsI5e(cA>zhizZJf$fp(b6%JAN-v=1IqH9v +z-{cia;~H)Rf|P^*0lWfyNIq%%5xIsuhCZv2hr9;kc+#i^-?4dtp8XaOz)Z +zJl4O+c&vXJxOMBF5LCdx@@tIi`u+h9pjzX)vdHU<>%4H=UI*t(-7Qz06AqwxBxrSq +ze=i46$5q~}d1&r($Hcs^+svAdXY3y1TJ{eSwbw`OM^u^z(@|4H8KMp&>W>h01mVa> +z5r<-|g5QKSlvSH<)*qHMm-*nd9YB0!$diAqmtNNb-wsn~T-O45xp5V{-0yL= +z*O)=)Z~=>?68txq+gjr~sr0W0r+=gIc$Q0ElM0LK{n--D9@Vc2ycNpUf%9;wdTsFk +zE#gdr^Dxb;H~$hz$kp6qhIlpiy3027qTI~dI9Kx^IRAosXe*ESb2l7Dnp~{F5pXW( +zanJpW(i|{p1GFFxm@*zKJ_}Ak7LCW-%93%vt!&?_l2;GRphEowOJ>!$7DT>gTnpmP +z+jm`A633@#DveULOkLgO&ZNVfTAV8doLg +zpLOq%qhVk@$h|2P +zN?rs`y-UEUcPaQ&_>`v14B7z;YQg{}UIgbW4XYV=qA4`6{i%eyrt@H62ZhFCsf&!q +zQr9BR520KgIL{aD!qdl;uB89LO6sry%Kwb(?JncGlIY(9PXAuxI+a{oeIb4-@e3sG +z4~89y2a$mO!{AIjVmwYfiulXvyroi_JjM~o8$6#tpl`}oVx5#c`km76(kx5BtCAYSQI8rKCx +zUX3_>BVny^t!@I<)qC!r4$#nmK)lLs1m`i?2~HXN!71Y)_~(;&i{-c(w9;Rl;&z{s +zJll0Lz%HwwNVOKrmV6%zW_SP7HHbwZ4LL8cIhYibsObgB282!* +z_${e0b$lw{{+7T`heD&^e0%E*_-XK80B8LCw_1Gd|3(a`*)j;{=GF`T75Gnsv!Dgz +zIt9PM6fA=4`!v1&;< +z5Kjw@;Cy3l8xrutE!*9(Gv&IX6KQDfcDr_qxd&0X7xcP)VwTU+O$X^m5PqEGU^>XY +zp$tKWjce~bIgI$IV~9%gL^|q~lNq9Jf^(_VyzRs@Q17liOIm4gN42A7cS!%Q)jcNv +zx33Lj*nX#Rt(>ZLrGpf7n_1_M=3XDQFGJLRM5T=K9vv-h$Q{ssM$$o2qZxv%fyvHZOwgNwPl2=0Iq+AVwtaxg-R8IZ +z&U7+X!y%N&Gp@5ho^M0c=c;x;JZv3 +z!Fi?94E|dz%|-Atz?Z<2;ET7|=}Bk&sGofKO>QII;{Qj5B40MHGyb`3_4JQb<2q5V +zM#pRLXX16^wI$Jjl3T;UMX5{OfxP57yUWe2b=`5Yd+@2rvoGKt-HG8mTXnmmGCb9b +z;e4k^zj2k}I=cjrUlYR!mjm6#5QqNL@MroZ&)=GUZFx5Wtztkebj!Id$iM}WYh3&1 +zyyU@uB->s5G`SMxf~kU?d;pvU&l!&oym{mCfwyX01^k^q;QY#7GlLdv2Kh~%)Eket +zj$~VCoDy%aVq6#9W0>OgG#C99icNO7zO87h0Pk*#&~yg +z&bT&qVM^v;>#<@6t@QV(bk(>PO1@!S*95=RY`Fczh0dOUr;oo)7%1uRyFwsd+AV>z +zF<04I>qU?5p1c^?5=%=T>rP2UGwm525s(; +zm{aX$j>C2#>^jQs24{JFNJIYtaQY8=?q7~$KSN0HI1&$oGtd|k(0>A){*%Ui!+x=d +zH1c;lNbmZ(-!8(C_#ktV9#^e57 +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 +zNy_?$FG%~Qe-8M=d9NCC`KmlW{;!rBY=CNXM# +z@3Lw~oCo+0*-ixFM?Uo!k2~v!|G(hOG?2l6cG@ekBaU7=&HP7LZ9H5SGVqlQd?N#& +z`c{Vc!qb;-DjgFq*#Mn_r(p_~!Fimn8P}%yHUie}vgJJN$ +zPCTIazk@=2rL7U14YY!@fx1~AC;bjMZi)Hd2?@vt!I@y#xK7PEn3@rA&i%M?oigz^ +z{pEiqVc>u%3d_sT8pZDF+@r$yh5_^<_^FpuFxOSY6j=R9wK(BG_ +znEw6Bbxo<^;gj9{ua{?Xd}1?U1GRG&Fb&Qvc;0wi*aA2UTQ-iu{H5>g#Jf4b8 +zBq)F)33s?b&OkZe^8#xgn)BQ-F{kp)97nC03-iL2IBPsU_U4So6JPj!A1CI0o*#et +z((;3lm@BJxKJYJaGXST5@`v7E=i}*+B?nyQ{l@E)rx)ZKQ;q0bzSxfzo +zgUs|F0l$y(d!9}4JnS1|1L^tiF@p{`vbAl=?~N-#iE;3pUkCnW +z@E-7g1MdZY8TkCK@gWjB68t74Aa4TiL!i|RJny$5&R5}Iy3M73Cg|Tb$d^fDK=o<} +zME{Wtyzr3|`!|E9PY_$jU#A)3Q(2dB&Y8?iVg!L+ghD65`C{+_ICsn|7c(T-#DD`y +zP3a$5kNVDZ^)BGqd(u7hW;v7PnOWB=&4q4HbMl-^ip(4@%~JAgOC|qQ8TYcdyWT8k +zEWYB~jd6EFhJJ9iyAIC3%Io-Dn6Dk(t_5y;grBi47`RCcflr~JIdB#^C& +zZ>-rFOBH0tg})D#vV#F|>mV&}-v0)FHc*^_H*Rt5pB*%rA?~2rc-%qvR-mYXA#gUZ +z2(Edzj+n%f8REpt#^c0U>!D*R*9v|srmXn!;D3MM^0Wj7Ryqn!sZ0J40#WLU47>q+ +zIwVf?r@6cMt;thUoPh!JkA)aC9t$yv_!Oe}kD<=nkarQ>gz%G)wGjqTh-PpKu>?*b +z)-v$iCqn#hp`f-W>>!9c?!*A@e!a%kAMYed^ch!$$Opl>-Ar%AFOdP`*cE3o3`n}i +zTI3m6?w>*P|%F=9UV)|S>w`hYR8`@tRc{CSS-oJ +zNm@_3AWB^U&bup>#$!dB;O~{NExQc{o_zCng~YsdS_978Y|Y^PR05p-^C=j3UvANO +zEZvgvxU+_=Q0QN9A-)9uC-B-+y#F4(SmMV~*15}Wk!>O8RBu;v5ys^juZeh`@%_Si +z_dFk*e-%@R`2388BG28AZ;_ivrRJo`=p-L3f2-73f!MqU+L#@*;PM?d9=AMVT+>jB +zwPc7x?S@ZFbN{JWdm+wCfX@`Jbl9XGBC=syWg|0&}tCL5bZ{AZrJeYGL42Eo8U +z^GNVa6uJmb|0Uyb;vGge+5C@cl@5&aD?NMo5XYE-is0y6RsMfg7 +z)3(1Z*LoN@puzZl@!^8+2LC5)r~MiDa0WguJbk!m0tTAJ04lMNfiGv^$)}!J(dNKY +zi7s?7YzCFI7?O^FQ=xI=Dk=RZ!RbF`JSbW!BjvFS!*@~88u-npx%a(8p3XiWYoIqT +zbjUN?7YF;v~%9CfEdrB5o)Q +ziCO48I15dj8~ho+G|i>|{n9-uN;G5`&hfN5`h|^wGi3O6xf|H`rWdz6{GXyGkrX@lb0IbFZ>kvR~wI~ +zt_J>mUR#U!c1OY=Sgjbq=dbI>50Db%3viwl8t3!WUgPmhOv3+1P`s=-6#{Kvu1bQ@ +z;=p%Ih4EO~dE;K$bdBjB6&Lt8>Q6;0jn``bG&GrEzi>+3fj}l*IzcD=DRtLY0`a2% +z5d2kXufI6uKigLtOE+p<3!>Cx8T^;vPpRuK^zk(glujk)V4&0+;6KKkWtD_L3*foN +ztNea&UYQMob7R{q4UI8Q)q~=!m1jlVi#^e2E +z+PDgm1;rOK_~*VfG{F6(=%qNR(NK>8_hJn+7>^5Tg?|&SUwXi~AN6g;(f)bT$$Ocv +zG)~Z$fhQ|Z?B8Tu72<~17Wr=-REhFSf<)YSD#5w$RA=C0;5>SYFFj$QsYIn2v{Fh} +zbK(Js0r>OWG6}wjDO<|GH_}}CkEJfF3QEi)P!0IjIYDYp)EbZDbikjdiZ1X^@T69` +zKP2Xs-SdjTxdWF~2TuP1aQgRM9{jg>dj9)fdAvb8Yq%nCCTP#Vdou8$41DqmoYa_L +z83S&>@tsu@3L;M$kEfs~17F$z*A#p(8TO`!g$>ABm%MHCF60& +z%f`1mmOT1c@!a3QWyhnnC+>Le)q$6CYOW4^$Kh%`R$>GG&8I!fSEE1ct_gv7R_tL*fUpuXchTz`1h(oc^QW+t1_lINF4P +zZ&RzjE+jq|E2r#rfsdo0{@0(FPZ-w~z}Gsagr|>VoqHNK-w*;Zab;uRg(#@$hQR4R +zbyMJcTibHrsU2@$TM32)-#3?R3W1n-@Ic^9Jox6o>A%<I%`;9O4Jdg1}g2Lq>nRY%}VF!-Lpe}Tp(jHmX?-2V!O`OYw4 +zdzFgMg7NrLchPvfU2P%`@As6wH^i5t#+}uhd|HZ9b-yn-u#>i~z*$(k@wl)K<8fgF +zh+~EMMKA%wze15&aJ~Z9e8?9RCn$e^D3tp`m2oZfavVL??@xt5G)!d}Fl}5D(|->B +zyx}wtfATfs=}+o81r?QiAQW@~c)xM&fPn_!Pd;XRzxXr$IQ%uf9fa~dJ{Z6|OPj{8 +zkU-DIWl5sj7pnY1@T76w*yx`N4*ygl&kR~A&vwP+P@*gY?*ivZZ4;a)ubkVp0qI{8 +z(~y@o9Dk8tZ(KVrLB|c?=q%A}T$P}IEBJ*e1Zp!wti%WsJO}=x;7mM$1oWQ*-||n- +z|Fjw6#LM8^C#pZF(s|{$Pqg<0{&gJ2-QawIy|)J!^W0eaY(TuR^c#D9R~WC=`M(^Cs|EvjIMr?s*m?Lh8&~Ccn6Vpc3myz>YWI&yFj4L!sPPYCQKBp|@eN)Y^b} +z&gzWE9kd|<5929t?gy23hJtpy@30RBuJ)0;!T_%Jyn6!Y;>|Z6FWy4qI~K3beX3kou?PNKj5Ei@x8rXX1DJR@LxL6fGeJqeS3*1HYHtVU +zVq8g?VaKA7!DaV`KwQ( +z?vanl?Iy0tqJQ*h;-yhxT=n3}sDwXPMkoBaRC~Z}sXj$QCK7#SNZ0FL{c)*_D`X62 +z);n%Iu6GuBSnnMCS#QH|kk?kMUxD*5@L*pBXQ5@E4S{&|Qf2%K>6I7#)!&k`DJfN~CKL}ET&Y6ItqVd0-bp**z4Kj-;X+CL?lFvD?6d?W +zUYWzjw^p*(Uy2xmfdy?K!R;EMb#6x8OoCkZ?=TGP_`A1C(DT0eG%Xqx#3XSg< +ze=fQr__Kkg47@+hCBFvZi=Jah@Kbc0_(JG_`|T(=7wJj{zCoT!N_KlB?+XbSs2rS& +ztMH4#pNp&dNZ?!(HO6&KY$=qU|5`J|i>?)cxaj7=+n`XxmqKEmBAdXuR_4EiXP~^B +zxP$?``&jp{ApxhLbUbk0#cT(sqJ7(3`lqBr+lHNYB`Urg5>V>7uLMr1=Z#Zpo#h4N +z+e)YP7sCbuQR=3NkbqJzgH!5Na7x|u)ewhDr&?j4)QjMhdg9+hAWEJ1THutr5S&Vv +zdVc)h159H8rEa`GB%sty#$&0Qjc-e>`pcsmaqi~Fe6GSksawAh5>x7Sa7w)lPN~Y`Za7x|sozNH; +zb@g`x7p1rMzeJ)J21+*qPN^rr>0kG~kbqLJ91A=sE%{f?5KFygJeE55`ymje?f|FM +z8{kwr@dJsY{qK*YZc~GCO5F)gsaL@%^~`*T!$qC@!@zf3|Cho*sVl)L^*lJGZe0io +zg4Bsbn{g=Z=fB+yvDEztM5#ByDRt*hLSjnY4bDZq{*zP~K&cZy4V+T9fm7<*p9OzP +z-49OX#-?sern +z9@0?ovOfe)p(-{!k9Ddv9_!R-e1Fi%&vh#d6lxlrLe)GG3ZhQKe+ryBje%3Ar9a_Z +zN1>|zF9hORtp(@O8wRIxGn*j}mCH@|Z}dsO+kzeEnIV=m-*_x(#a5sosr)8?1P@N- +z8h2S@@loYonf8_+y)aOsesD@U0^W9-yYGwgHhgy8a#Bb{rMkhX_#`+L&pA27;qFri +zZt?wEnuURq&z~9sQSk-ivEqxyW5qWShX;F4c56sL$qSQ#bFtQfQ}KFmD&7JvieG#r +zQoQ7}kcWy_gH!QNa4J3vPQ@3&cPQR_dPq#gb8-Ub_cpYi8TgxUP9Fg0dsjzx2Y-HB +z%F6C5yg_em^Ly-8ZGhgXCa*jz1Y$vb?%0=PD;&)AW*zn!f85G%iNvt+{qj5Ood9RO +zQyJpSz@OhXICcspAMLy{wbjk2C8_f=c>nZ@wS{w@V^4DF|G|im+yY9 +zgMkC;jjIy8)!z)x1_q65K~!`E@wd4izM~leO`m9h_|L+hN-Tl%YdTkrYeD>i+BMu^iLX(70NNL@k=oUxq;uhBXJ%Qa6lnA6Bike6BmaBJEox2 +zT{|voz8vO@P*(*w(^MK)J?LKzPX8L?aapyVpPyda{C1Rj8=yj6e5$*DJb88j12!Si +z#qJU5;R2dlGvw=XkNump+l|rX_+;uH40~x(Qrn{!oF7uu2hQpTjBEAJgPen&pPK#v +zpflW=QcD5tV>V7@J;S|R%{;y)n9kjzo$&acM%L@m)f}SIe*v8Si%7%tONejZKKzQb +zK+7<27FLmfUst>ie#WWp;;+c$GSQ~lb+xRz8@`e}=jr@9<>b@C{`TZ4?k*X=!(M21 +zRZ;Bsi+#sO;1^^3Zp=;zINK;gJo;CF)4$R<7Q4SDsfK~uQ9}mant=~w;KRms+3{PC +zN1m3VV(B?c{}{IcsuTxIg7a&Vr;wNvHV1wHr}C0>eBSi+EjzB?GDu?bmJGZz1Mkbg +z=fD%E`+JG$j_1vwmw8WQr&0RHf^ogfBVRJEl9pkutQlA3$Ty7Z+3NveTnycIqG4HE3bF4rOqP_r8YkkyuM5VdWM{UXwwHZ;%5w*ofZ9`O= +zJJL}v>C6zd2b`DkeaQC0Q{9cCoa_C1GN)hwd0vPzhSGUnH;i~Ze8&*)M$G0o_)Xwb +zNONPBJMVtkU}>MtkY@p${VaoXRjwP?RrVsZvjJ{--BZ7j+;b+Ka@@63@(s8(-$>@X +zoXysr8R>_x#Y)i!o1m# +z7xgO +zQ!qRQ9Zwk7N~zGaaZP*)63-ad#N@Mx&&2b_QyPdjKNb*(d=Y_oQ)CI8XX|C-8h-;H +za=ZebIwgJ177ux>n?XC^fK6~25FXD7Yek+oJosO-n +z9lj;`P2REM`E%13Gc*)lcM$llc#zTF4byg +zRZXiHlYjNmZd|L_50yK>8}P)b3vuY*15W>5&;4sweEK_p1l*B^5Qu!(xa#r$+dKcL +zD(gItbFTsSL9UX5fq_zL(iIgI1zS?R)O9G#p3b7%AnGb3i( +z*qc2^jAo?hCT`8>j&0l)ON*HW(?&PkptX{uD;WMDv7oc>&+~j)Klkow_s{8^UH;(p +zd_V8+&(HVg^FtY_mcld29!1Yl=&pdA*(bEo`c?o43hh?TRl` +z0{@%t9q)2;Jg0kJ>7$41&y;(Wy;VIHX)t#2&lnYdpRtR7wEc{VZ&n(ocg`9?hT>nS +z3UwR13|(#SQ3dEFYd{t7wCb=y6<^z+MPvC0Tejc71GJ5_@5Dx+U2`(|aYF?R8gKBete`D=R;)0_Whx(i>?u}uoqy@9C!7{Y0pC&utX2hR`&yNeE?}LpOIO^eJW+1!;t6fv +zJ)DoUU%Rf(2vVUXszQ5}{hU*0#^4(pV;4{8_y?3-$3JB3G6ZD1bo|f25mkUbMzpJp +zw7o}Vr2qfcL1ov=e*Em~W97!{%Q(J!+T&djtz33eMb!Ib#+>UJ+@oeewy}%HbOm#9 +z;xrE?H7ePksbss2J#tyCGxo@_+obYIyk7sPBgQVp7pM+vaqP}B%e$3u(j<@`(+N71 +zUB^FT?880AWcE*wu}i`FATyxyIT$t5#1>>6EffTl)6$;{XXyA +z^p{lTPlDSYOH4#CQqDH_$Wqlb^oo3o>e*#sa#{!XzQ4rW4$n;2Utx`)5W56LI4W3* +ze!;gfrPIa=!7^+U+=GLHd(kEM4w60~mSeGC1vU!)8uboN3BHTy{~(GnSFjRm9PDy% +z)Iq<4DQD~`D;#WdaL_@QgQO1`<$G8x_#12#tVF$oQx2j(vW;^ctZ}f*!BGeO4yJr; +z$6VoHn_v|VI-xEHNoQ#+!D7KmY!nou-U*#@5Zz@P=L+t_8V9=^9Cgs|V9F|KBNYA6z)9lNyf@<&q&upSVNiE<>07; +ze!*%?`IK0L6%MvJIOw3uK~l($vRLr9*yy01@P1zvSuRCRN@-GqEW-?Vnb%WMd7gjl +zWU2?pKJ$#@Td76{iRx=a4muf1(Jz%NOj;Sgx$yQ-){htV8d;WxsmP=3emDjnT;SB*TdM>nFKgRcfCUPZM8OJi~0Wda8KulVkp}pyP;%Ww-JS2jj$Y3lXl8&}v@u@F +zBdQCQ8>h%}_6UY3ht+a5o}-tMD>*NaT6RmDN>L(JX{Etcfs4|P8pa4qxgCe;VYEm} +zX@s}Nlq9|Lzqh5rZh7LnPrn0JfHJdheSF=4}_I`7B2BdH|)64qD`0RxQ+a1te0K82(_0yOT3G?*$)4t<3si~JeL{Q +z?u7Kqo&}6pa+y}?bPPx*+5W0=Bq{X2XYO9)!Rs79DJ3fRVpEK43_nEC70FX-RX}e` +zcS-_pSOT07w-jGtGaf}Ad&8BFPNs8BMcP#xUK&%@s%~Fp3XyJKYo|%kf6`sgq%M?6 +zYW>CRK9gFyatvxI%OqVWlk{P<^>eyBj3EJM&F8FuAB#V?r_x5jeAIvLS>n0_z0}-S +zWAVWiCUolhwUfP48q$TJO#NImN@xsvB{UVC5_%YEU)Ti~5i*I7^)OdI$_DI`YX$Ss +zHei>W_vN3uWP5Bqh%#2hyGeCSE@sJ4Y539;KVJ99@H`clPqVPFpN$)Yc*ULT!30^b +z26d>FpiU^&^yV)8N8c +zNjYpSEO7o*t$k>ogGQ0{lXUZ3*M1%K7&=9MT+QbN=4MY8+Q;CHi;xS9EYo^E@$(Xtxm`JKx1oFZO&o+qz~)+7{LRx%p6 +zzq@msBURW@ZP281j%u}%t_KIbmh2is41Gfik&Oq1mc=83oK)6LBI=sGBjR)ZQG$n3BOl9mSBww)4Po> +zW03k+)WbfPUTYrU%OJcT({E%co3Z#tYbLRg2#efcBFm6`0zrxO1bPMYkv4`&S7GiL +z>rsXp8A`cd-LvZxUOW)5#^@AXv|2YoAk%Y$CaC?-$y+~>%(q# +z=4y2!n|uwyL^e`CUcSrJQ~dKKdPV+Hy?fTpcmruktfOA4maEjP!_uUPI<7XlbS3r8 +z)WhmnuDrw^knD92=#}sx3ll6Re@OL^KG>axcO09@e@5V-Y#f`SU(uKkkL{K3$EX!q +zf5mQIzS}RhevGzA**vwdmsNJwILp4d+B1uNcNHZ!MR>K?^o=YC*HBH_{gW7cHHEQ% +zf}q4!A4^AVGO=a$TtjbUW?R)j*ow4dX10}I!OET68z^EhWt&=L52)B9Q5h)@k1FYr +zk!Yms)lO=~Q*1f9ldX8K_D%;5i#<7o!(7{k=c?HdQdpUvs><|*Ri=zGnr`CM$(_xq +zGZM8l$l3Sx+u4>Xv`KQEd$O6lQrRjDMaq-aLcpW@c&7fDDm+t7{gEh%lyg<)BT+4~ +z_C&r){c{9Go~AM{RH=WC-bi`)rJ>`Ow3{QAz~RrpWY%#BSbB5B61YL-PJJ`=u*z*Q +zx@6yjMrI$ja=onT9*<7Svd~<(kzS66H57M@wW(fUH3 +z7V*?Ls>L?*88G>y80_ILmZD!NoHhENlR5UG#r;#RxLmMZ*=S=iZoWBOFALaX7-G=% +zIBKU5k6}8u`LHwOax>{AtNADqSsxOIPk}P5Do`!5J|woP)cFWfmP6tW?rvNmFliq+`4mDyAy +zX;Q>VW_UU}hs=^mEF~8kC)sD0UWUR>Z&hZPIFZvPN65RwQu5F-V82y(gEJ#i7usA +zBQJvmRijKWAGM4n4=L;&KNoEow%_Frh!1v3Zf6O)uWQsW8iQ)etVjLrcA7Mw?1JNE +z7nEOxKHgdM$W^(|n#_`R`Rp@xC!>YkH!M@j^cZ-jMHH#GlqZoljkSIfWdc^7k?F{T +z655F_BCNyeOwQ8or!YN}v7SN+Ar4;8M>i=k>J?P789UPZF$iWd>v=dOiRK}CdPLUw +zs?xbAnjTT<4W?JjKoeO%xXbXc4E{(_U1$_}shX@OO|6`obc(Diniy{7 +zGQ;kKT82{oUX6)z6Ip!lG}7dNx58SW?f*f`s|6)n=d +zR@T6gzinYXW!JN4oX2{OkHh|XtY^nOtHHGkY0Sp;3~F=OnNUNnR7&BGba@ThD7*gQ +zcU?IaR=c`Ux!YPKeIW>8NN^r`wbmk3?6xw|P-`WkNv^u(YEZ5+_V8*!Ew9$fRfSwN +z@X9qF!97fWGlmE>?U5MI(w>gWXRSr<8L?PcZ%xCe&st+$b1+03_x!v%Vje05cOodb +z8$*IhKuGbL!6;m}~NYI76Uo&x! +zN!;*j#)v|YHdiKw1dEWjm*5jF!M6|;EWwbV0D1LHz0`7wZm4JKWeC!Siv27#;dz!? +zQ7@HvUVI|K243-HX7G8YUxgt8O=4gB0%Hu?F?hunmBAOJ1usy_XrSRiS(3Pvr4)@CysxL_oOrO@xF4pThS$vg!!@!uBHw2>Z?> +zBpf&j-yt&UE%=3-E+9Zg=fA~f<3zhP_L*0$4EJ4c!S^cV<_qu(x4wmd(DNBW!XwoG +znOyc6{KC|?5fBbg7Z$$_-)m%kAN;}^>cS&$BP6WqgRhA!Xn|k2p#=e9cOOE+D=qK^ +zMZXBYaPapC2+J=cWQYF%-|Gz5^usTVYDGYp*ou&_`6_(>LbkTTFWfSKfE{i_NZ9ZN +ze9fXCgP$C6e9(iJnyox{>pKXEVc;tdrX8l?D!1o5({x1B& +z4Sz&HSRRd#F!w$9-Xzmw;TPV}j({*X79pYMG<-+M#MAH#ODzP13;rD;;g&e~j*_e2 +zhhJDX5&>aV2SUQ^PWav;o8#dZmVShQucT^D2nmxXz}H45jD%l!hV2&?Oh8C@lI=T2 +z)=h%nW+DQ@s3e4h0~zqWBjKs=3)80}AncotknpZ)@Es@5%z$6GY#IW>ff)!1Yp9t@0)JVaf1d?rG|cIxkvQCaW{2dE3PvJes`XTtYKvXr_oHxmKjPU^y9>LcTqe +z!nLyy5=Kpj?-W@)8-8K>bOeM|vk?*&Q2#gbICWt;bz$-xgoIT^@V!T7&4FLoUX1`b +zB6i0O_%Jvk>6vy;bI%U=+9@u}hM!Doh<2W+)?Kpq`>4wV-wn50)2ssX4}f04#da&l +MedsaxPFuJAC&$n7YXATM + +-- +2.20.1 +