| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: disasm.c,v 1.13 2021/02/23 20:15:04 ryo Exp $ */ | | 1 | /* $NetBSD: disasm.c,v 1.14 2021/02/23 20:26:50 ryo Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 2018 Ryo Shimizu <ryo@nerv.org> | | 4 | * Copyright (c) 2018 Ryo Shimizu <ryo@nerv.org> |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
| @@ -17,27 +17,27 @@ | | | @@ -17,27 +17,27 @@ |
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | | 17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, | | 19 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, |
20 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | | 20 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | | 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
22 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 22 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
23 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | | 23 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
24 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | | 24 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING |
25 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 25 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
26 | * POSSIBILITY OF SUCH DAMAGE. | | 26 | * POSSIBILITY OF SUCH DAMAGE. |
27 | */ | | 27 | */ |
28 | | | 28 | |
29 | #include <sys/cdefs.h> | | 29 | #include <sys/cdefs.h> |
30 | __KERNEL_RCSID(0, "$NetBSD: disasm.c,v 1.13 2021/02/23 20:15:04 ryo Exp $"); | | 30 | __KERNEL_RCSID(0, "$NetBSD: disasm.c,v 1.14 2021/02/23 20:26:50 ryo Exp $"); |
31 | | | 31 | |
32 | #include <sys/param.h> | | 32 | #include <sys/param.h> |
33 | #include <sys/types.h> | | 33 | #include <sys/types.h> |
34 | #include <sys/bitops.h> | | 34 | #include <sys/bitops.h> |
35 | | | 35 | |
36 | #include <arch/aarch64/aarch64/disasm.h> | | 36 | #include <arch/aarch64/aarch64/disasm.h> |
37 | | | 37 | |
38 | #ifndef _KERNEL | | 38 | #ifndef _KERNEL |
39 | #include <stdio.h> | | 39 | #include <stdio.h> |
40 | #include <stdbool.h> | | 40 | #include <stdbool.h> |
41 | #endif | | 41 | #endif |
42 | | | 42 | |
43 | #define PRINTF di->di_printf | | 43 | #define PRINTF di->di_printf |
| @@ -909,53 +909,53 @@ regoffset_b_common(const disasm_interfac | | | @@ -909,53 +909,53 @@ regoffset_b_common(const disasm_interfac |
909 | op, | | 909 | op, |
910 | ZREGNAME(0, Rt), | | 910 | ZREGNAME(0, Rt), |
911 | SREGNAME(1, Rn), | | 911 | SREGNAME(1, Rn), |
912 | ZREGNAME(r, Rm), | | 912 | ZREGNAME(r, Rm), |
913 | SHIFTOP8(option, | | 913 | SHIFTOP8(option, |
914 | "", "", "uxtw", "lsl", "", "", "sxtw", "sxtx"), | | 914 | "", "", "uxtw", "lsl", "", "", "sxtw", "sxtx"), |
915 | 0); | | 915 | 0); |
916 | } | | 916 | } |
917 | } | | 917 | } |
918 | | | 918 | |
919 | static void | | 919 | static void |
920 | regoffset_h_common(const disasm_interface_t *di, uint64_t pc, uint32_t insn, | | 920 | regoffset_h_common(const disasm_interface_t *di, uint64_t pc, uint32_t insn, |
921 | uint64_t Rm, uint64_t option, uint64_t shift, uint64_t Rn, uint64_t Rt, | | 921 | uint64_t Rm, uint64_t option, uint64_t shift, uint64_t Rn, uint64_t Rt, |
922 | const char *op) | | 922 | uint64_t RtSz, const char *op) |
923 | { | | 923 | { |
924 | int r; | | 924 | int r; |
925 | | | 925 | |
926 | if ((r = regoffset_option_to_r(option)) < 0) { | | 926 | if ((r = regoffset_option_to_r(option)) < 0) { |
927 | UNDEFINED(pc, insn, "illegal option"); | | 927 | UNDEFINED(pc, insn, "illegal option"); |
928 | return; | | 928 | return; |
929 | } | | 929 | } |
930 | | | 930 | |
931 | if ((shift == 0) && (option == 3)) { | | 931 | if ((shift == 0) && (option == 3)) { |
932 | PRINTF("%s\t%s, [%s,%s]\n", | | 932 | PRINTF("%s\t%s, [%s,%s]\n", |
933 | op, | | 933 | op, |
934 | ZREGNAME(0, Rt), | | 934 | ZREGNAME(RtSz, Rt), |
935 | SREGNAME(1, Rn), | | 935 | SREGNAME(1, Rn), |
936 | ZREGNAME(r, Rm)); | | 936 | ZREGNAME(r, Rm)); |
937 | } else if (shift == 0) { | | 937 | } else if (shift == 0) { |
938 | PRINTF("%s\t%s, [%s,%s,%s]\n", | | 938 | PRINTF("%s\t%s, [%s,%s,%s]\n", |
939 | op, | | 939 | op, |
940 | ZREGNAME(0, Rt), | | 940 | ZREGNAME(RtSz, Rt), |
941 | SREGNAME(1, Rn), | | 941 | SREGNAME(1, Rn), |
942 | ZREGNAME(r, Rm), | | 942 | ZREGNAME(r, Rm), |
943 | SHIFTOP8(option, | | 943 | SHIFTOP8(option, |
944 | "", "", "uxtw", "lsl", "", "", "sxtw", "sxtx")); | | 944 | "", "", "uxtw", "lsl", "", "", "sxtw", "sxtx")); |
945 | } else { | | 945 | } else { |
946 | PRINTF("%s\t%s, [%s,%s,%s #%u]\n", | | 946 | PRINTF("%s\t%s, [%s,%s,%s #%u]\n", |
947 | op, | | 947 | op, |
948 | ZREGNAME(0, Rt), | | 948 | ZREGNAME(RtSz, Rt), |
949 | SREGNAME(1, Rn), | | 949 | SREGNAME(1, Rn), |
950 | ZREGNAME(r, Rm), | | 950 | ZREGNAME(r, Rm), |
951 | SHIFTOP8(option, | | 951 | SHIFTOP8(option, |
952 | "", "", "uxtw", "lsl", "", "", "sxtw", "sxtx"), | | 952 | "", "", "uxtw", "lsl", "", "", "sxtw", "sxtx"), |
953 | (u_int)shift); | | 953 | (u_int)shift); |
954 | } | | 954 | } |
955 | } | | 955 | } |
956 | | | 956 | |
957 | static void | | 957 | static void |
958 | regoffset_w_common(const disasm_interface_t *di, uint64_t pc, uint32_t insn, | | 958 | regoffset_w_common(const disasm_interface_t *di, uint64_t pc, uint32_t insn, |
959 | uint64_t Rm, uint64_t option, uint64_t shift, uint64_t Rn, uint64_t Rt, | | 959 | uint64_t Rm, uint64_t option, uint64_t shift, uint64_t Rn, uint64_t Rt, |
960 | const char *op) | | 960 | const char *op) |
961 | { | | 961 | { |
| @@ -2020,27 +2020,27 @@ OP3FUNC(op_ldrh_immunsign, imm12, Rn, Rt | | | @@ -2020,27 +2020,27 @@ OP3FUNC(op_ldrh_immunsign, imm12, Rn, Rt |
2020 | PRINTF("ldrh\t%s, [%s]\n", | | 2020 | PRINTF("ldrh\t%s, [%s]\n", |
2021 | ZREGNAME(0, Rt), | | 2021 | ZREGNAME(0, Rt), |
2022 | SREGNAME(1, Rn)); | | 2022 | SREGNAME(1, Rn)); |
2023 | } else { | | 2023 | } else { |
2024 | PRINTF("ldrh\t%s, [%s,#%"PRId64"]\n", | | 2024 | PRINTF("ldrh\t%s, [%s,#%"PRId64"]\n", |
2025 | ZREGNAME(0, Rt), | | 2025 | ZREGNAME(0, Rt), |
2026 | SREGNAME(1, Rn), | | 2026 | SREGNAME(1, Rn), |
2027 | ZeroExtend(12, imm12, 2)); | | 2027 | ZeroExtend(12, imm12, 2)); |
2028 | } | | 2028 | } |
2029 | } | | 2029 | } |
2030 | | | 2030 | |
2031 | OP5FUNC(op_ldrh_reg, Rm, option, shift, Rn, Rt) | | 2031 | OP5FUNC(op_ldrh_reg, Rm, option, shift, Rn, Rt) |
2032 | { | | 2032 | { |
2033 | regoffset_h_common(di, pc, insn, Rm, option, shift, Rn, Rt, "ldrh"); | | 2033 | regoffset_h_common(di, pc, insn, Rm, option, shift, Rn, Rt, 0, "ldrh"); |
2034 | } | | 2034 | } |
2035 | | | 2035 | |
2036 | OP4FUNC(op_ldrsb_immpostidx, opc, imm9, Rn, Rt) | | 2036 | OP4FUNC(op_ldrsb_immpostidx, opc, imm9, Rn, Rt) |
2037 | { | | 2037 | { |
2038 | PRINTF("ldrsb\t%s, [%s],#%"PRId64"\n", | | 2038 | PRINTF("ldrsb\t%s, [%s],#%"PRId64"\n", |
2039 | ZREGNAME((opc ^ 1), Rt), | | 2039 | ZREGNAME((opc ^ 1), Rt), |
2040 | SREGNAME(1, Rn), | | 2040 | SREGNAME(1, Rn), |
2041 | SignExtend(9, imm9, 1)); | | 2041 | SignExtend(9, imm9, 1)); |
2042 | } | | 2042 | } |
2043 | | | 2043 | |
2044 | OP4FUNC(op_ldrsb_immpreidx, opc, imm9, Rn, Rt) | | 2044 | OP4FUNC(op_ldrsb_immpreidx, opc, imm9, Rn, Rt) |
2045 | { | | 2045 | { |
2046 | PRINTF("ldrsb\t%s, [%s,#%"PRId64"]!\n", | | 2046 | PRINTF("ldrsb\t%s, [%s,#%"PRId64"]!\n", |
| @@ -2090,27 +2090,28 @@ OP4FUNC(op_ldrsh_immunsign, opc, imm12, | | | @@ -2090,27 +2090,28 @@ OP4FUNC(op_ldrsh_immunsign, opc, imm12, |
2090 | PRINTF("ldrsh\t%s, [%s]\n", | | 2090 | PRINTF("ldrsh\t%s, [%s]\n", |
2091 | ZREGNAME((opc ^ 1), Rt), | | 2091 | ZREGNAME((opc ^ 1), Rt), |
2092 | SREGNAME(1, Rn)); | | 2092 | SREGNAME(1, Rn)); |
2093 | } else { | | 2093 | } else { |
2094 | PRINTF("ldrsh\t%s, [%s,#%"PRId64"]\n", | | 2094 | PRINTF("ldrsh\t%s, [%s,#%"PRId64"]\n", |
2095 | ZREGNAME((opc ^ 1), Rt), | | 2095 | ZREGNAME((opc ^ 1), Rt), |
2096 | SREGNAME(1, Rn), | | 2096 | SREGNAME(1, Rn), |
2097 | ZeroExtend(12, imm12, 2)); | | 2097 | ZeroExtend(12, imm12, 2)); |
2098 | } | | 2098 | } |
2099 | } | | 2099 | } |
2100 | | | 2100 | |
2101 | OP6FUNC(op_ldrsh_reg, opc, Rm, option, shift, Rn, Rt) | | 2101 | OP6FUNC(op_ldrsh_reg, opc, Rm, option, shift, Rn, Rt) |
2102 | { | | 2102 | { |
2103 | regoffset_h_common(di, pc, insn, Rm, option, shift, Rn, Rt, "ldrsh"); | | 2103 | regoffset_h_common(di, pc, insn, Rm, option, shift, Rn, Rt, opc ^ 1, |
| | | 2104 | "ldrsh"); |
2104 | } | | 2105 | } |
2105 | | | 2106 | |
2106 | OP3FUNC(op_ldrsw_immpostidx, imm9, Rn, Rt) | | 2107 | OP3FUNC(op_ldrsw_immpostidx, imm9, Rn, Rt) |
2107 | { | | 2108 | { |
2108 | PRINTF("ldrsw\t%s, [%s],#%"PRId64"\n", | | 2109 | PRINTF("ldrsw\t%s, [%s],#%"PRId64"\n", |
2109 | ZREGNAME(1, Rt), | | 2110 | ZREGNAME(1, Rt), |
2110 | SREGNAME(1, Rn), | | 2111 | SREGNAME(1, Rn), |
2111 | SignExtend(9, imm9, 1)); | | 2112 | SignExtend(9, imm9, 1)); |
2112 | } | | 2113 | } |
2113 | | | 2114 | |
2114 | OP3FUNC(op_ldrsw_immpreidx, imm9, Rn, Rt) | | 2115 | OP3FUNC(op_ldrsw_immpreidx, imm9, Rn, Rt) |
2115 | { | | 2116 | { |
2116 | PRINTF("ldrsw\t%s, [%s,#%"PRId64"]!\n", | | 2117 | PRINTF("ldrsw\t%s, [%s,#%"PRId64"]!\n", |
| @@ -3006,27 +3007,27 @@ OP3FUNC(op_strh_immunsign, imm12, Rn, Rt | | | @@ -3006,27 +3007,27 @@ OP3FUNC(op_strh_immunsign, imm12, Rn, Rt |
3006 | PRINTF("strh\t%s, [%s]\n", | | 3007 | PRINTF("strh\t%s, [%s]\n", |
3007 | ZREGNAME(0, Rt), | | 3008 | ZREGNAME(0, Rt), |
3008 | SREGNAME(1, Rn)); | | 3009 | SREGNAME(1, Rn)); |
3009 | } else { | | 3010 | } else { |
3010 | PRINTF("strh\t%s, [%s,#%"PRId64"]\n", | | 3011 | PRINTF("strh\t%s, [%s,#%"PRId64"]\n", |
3011 | ZREGNAME(0, Rt), | | 3012 | ZREGNAME(0, Rt), |
3012 | SREGNAME(1, Rn), | | 3013 | SREGNAME(1, Rn), |
3013 | ZeroExtend(12, imm12, 2)); | | 3014 | ZeroExtend(12, imm12, 2)); |
3014 | } | | 3015 | } |
3015 | } | | 3016 | } |
3016 | | | 3017 | |
3017 | OP5FUNC(op_strh_reg, Rm, option, shift, Rn, Rt) | | 3018 | OP5FUNC(op_strh_reg, Rm, option, shift, Rn, Rt) |
3018 | { | | 3019 | { |
3019 | regoffset_h_common(di, pc, insn, Rm, option, shift, Rn, Rt, "strh"); | | 3020 | regoffset_h_common(di, pc, insn, Rm, option, shift, Rn, Rt, 0, "strh"); |
3020 | } | | 3021 | } |
3021 | | | 3022 | |
3022 | OP4FUNC(op_sttr, size, imm9, Rn, Rt) | | 3023 | OP4FUNC(op_sttr, size, imm9, Rn, Rt) |
3023 | { | | 3024 | { |
3024 | if (imm9 == 0) { | | 3025 | if (imm9 == 0) { |
3025 | PRINTF("sttr\t%s, [%s]\n", | | 3026 | PRINTF("sttr\t%s, [%s]\n", |
3026 | ZREGNAME(size, Rt), | | 3027 | ZREGNAME(size, Rt), |
3027 | SREGNAME(1, Rn)); | | 3028 | SREGNAME(1, Rn)); |
3028 | } else { | | 3029 | } else { |
3029 | PRINTF("sttr\t%s, [%s,#%"PRId64"]\n", | | 3030 | PRINTF("sttr\t%s, [%s,#%"PRId64"]\n", |
3030 | ZREGNAME(size, Rt), | | 3031 | ZREGNAME(size, Rt), |
3031 | SREGNAME(1, Rn), | | 3032 | SREGNAME(1, Rn), |
3032 | SignExtend(9, imm9, 1)); | | 3033 | SignExtend(9, imm9, 1)); |