Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2015 Cisco and/or its affiliates. |
| 3 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | * you may not use this file except in compliance with the License. |
| 5 | * You may obtain a copy of the License at: |
| 6 | * |
| 7 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | * |
| 9 | * Unless required by applicable law or agreed to in writing, software |
| 10 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | * See the License for the specific language governing permissions and |
| 13 | * limitations under the License. |
| 14 | */ |
| 15 | /* |
| 16 | Copyright (c) 2004 Eliot Dresselhaus |
| 17 | |
| 18 | Permission is hereby granted, free of charge, to any person obtaining |
| 19 | a copy of this software and associated documentation files (the |
| 20 | "Software"), to deal in the Software without restriction, including |
| 21 | without limitation the rights to use, copy, modify, merge, publish, |
| 22 | distribute, sublicense, and/or sell copies of the Software, and to |
| 23 | permit persons to whom the Software is furnished to do so, subject to |
| 24 | the following conditions: |
| 25 | |
| 26 | The above copyright notice and this permission notice shall be |
| 27 | included in all copies or substantial portions of the Software. |
| 28 | |
| 29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
| 30 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
| 31 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
| 32 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE |
| 33 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |
| 34 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
| 35 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| 36 | */ |
| 37 | |
| 38 | #ifndef included_asm_mips_h |
| 39 | #define included_asm_mips_h |
| 40 | |
| 41 | /* Encoding of MIPS instructions. */ |
| 42 | /* Encoding of opcode field (op). */ |
| 43 | #define mips_foreach_opcode \ |
| 44 | _(SPECIAL) _(REGIMM) _(j) _(jal) _(beq) _(bne) _(blez) _(bgtz) \ |
| 45 | _(addi) _(addiu) _(slti) _(sltiu) _(andi) _(ori) _(xori) _(lui) \ |
| 46 | _(COP0) _(COP1) _(COP2) _(COP1X) _(beql) _(bnel) _(blezl) _(bgtzl) \ |
| 47 | _(daddi) _(daddiu) _(ldl) _(ldr) _(SPECIAL2) _(jalx) _(MDMX) _(O37) \ |
| 48 | _(lb) _(lh) _(lwl) _(lw) _(lbu) _(lhu) _(lwr) _(lwu) \ |
| 49 | _(sb) _(sh) _(swl) _(sw) _(sdl) _(sdr) _(swr) _(cache) \ |
| 50 | _(ll) _(lwc1) _(lwc2) _(pref) _(lld) _(ldc1) _(ldc2) _(ld) \ |
| 51 | _(sc) _(swc1) _(swc2) _(o73) _(scd) _(sdc1) _(sdc2) _(sd) |
| 52 | |
| 53 | /* Encoding of funct field. */ |
| 54 | #define mips_foreach_special_funct \ |
| 55 | _(sll) _(MOVCI) _(srl) _(sra) _(sllv) _(o05) _(srlv) _(srav) \ |
| 56 | _(jr) _(jalr) _(movz) _(movn) _(syscall) _(break) _(o16) _(sync) \ |
| 57 | _(mfhi) _(mthi) _(mflo) _(mtlo) _(dsllv) _(o25) _(dsrlv) _(dsrav) \ |
| 58 | _(mult) _(multu) _(div) _(divu) _(dmult) _(dmultu) _(ddiv) _(ddivu) \ |
| 59 | _(add) _(addu) _(sub) _(subu) _(and) _(or) _(xor) _(nor) \ |
| 60 | _(o50) _(o51) _(slt) _(sltu) _(dadd) _(daddu) _(dsub) _(dsubu) \ |
| 61 | _(tge) _(tgeu) _(tlt) _(tltu) _(teq) _(o65) _(tne) _(o67) \ |
| 62 | _(dsll) _(o71) _(dsrl) _(dsra) _(dsll32) _(o75) _(dsrl32) _(dsra32) |
| 63 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 64 | /* SPECIAL2 encoding of funct field. */ |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 65 | #define mips_foreach_special2_funct \ |
| 66 | _(madd) _(maddu) _(mul) _(o03) _(msub) _(msubu) _(o06) _(o07) \ |
| 67 | _(o10) _(o11) _(o12) _(o13) _(o14) _(o15) _(o16) _(o17) \ |
| 68 | _(o20) _(o21) _(o22) _(o23) _(o24) _(o25) _(o26) _(o27) \ |
| 69 | _(o30) _(o31) _(o32) _(o33) _(o34) _(o35) _(o36) _(o37) \ |
| 70 | _(clz) _(clo) _(o42) _(o43) _(dclz) _(dclo) _(o46) _(o47) \ |
| 71 | _(o50) _(o51) _(o52) _(o53) _(o54) _(o55) _(o56) _(o57) \ |
| 72 | _(o60) _(o61) _(o62) _(o63) _(o64) _(o65) _(o66) _(o67) \ |
| 73 | _(o70) _(o71) _(o72) _(o73) _(o74) _(o75) _(o76) _(sdbbp) |
| 74 | |
| 75 | /* REGIMM encoding of rt field. */ |
| 76 | #define mips_foreach_regimm_rt \ |
| 77 | _(bltz) _(bgez) _(bltzl) _(bgezl) _(o04) _(o05) _(o06) _(o07) \ |
| 78 | _(tgei) _(tgeiu) _(tltiu) _(teqi) _(o14) _(tnei) _(o16) _(o17) \ |
| 79 | _(bltzal) _(bgezal) _(bltzall) _(bgezall) _(o24) _(o25) _(o26) _(o27) \ |
| 80 | _(o30) _(o31) _(o32) _(o33) _(o34) _(o35) _(o36) _(o37) |
| 81 | |
| 82 | /* COP0 encoding of rs field. */ |
| 83 | #define mips_foreach_cop0_rs \ |
| 84 | _(mfc0) _(dmfc0) _(o02) _(o03) _(mtc0) _(dmtc0) _(o06) _(o07) \ |
| 85 | _(o10) _(o11) _(o12) _(o13) _(o14) _(o15) _(o16) _(o17) \ |
| 86 | _(C0) _(o21) _(o22) _(o23) _(o24) _(o25) _(o26) _(o27) \ |
| 87 | _(o30) _(o31) _(o32) _(o33) _(o34) _(o35) _(o36) _(o37) |
| 88 | |
| 89 | /* COP0 encoding of funct when rs == RS_CO */ |
| 90 | #define mips_foreach_cop0_funct \ |
| 91 | _(o00) _(tlbr) _(tlbwi) _(o03) _(o04) _(o05) _(tlbwr) _(o07) \ |
| 92 | _(tlbp) _(o11) _(o12) _(o13) _(o14) _(o15) _(o16) _(o17) \ |
| 93 | _(o20) _(o21) _(o22) _(o23) _(o24) _(o25) _(o26) _(o27) \ |
| 94 | _(eret) _(o31) _(o32) _(o33) _(o34) _(o35) _(o36) _(deret) \ |
| 95 | _(wait) _(o41) _(o42) _(o43) _(o44) _(o45) _(o46) _(o47) \ |
| 96 | _(o50) _(o51) _(o52) _(o53) _(o54) _(o55) _(o56) _(o57) \ |
| 97 | _(o60) _(o61) _(o62) _(o63) _(o64) _(o65) _(o66) _(o67) \ |
| 98 | _(o70) _(o71) _(o72) _(o73) _(o74) _(o75) _(o76) _(o77) |
| 99 | |
| 100 | /* COP1 encoding of rs field. */ |
| 101 | #define mips_foreach_cop1_rs \ |
| 102 | _(mfc1) _(dmfc1) _(cfc1) _(o03) _(mtc1) _(dmtc1) _(ctc1) _(o07) \ |
| 103 | _(BC1) _(o11) _(o12) _(o13) _(o14) _(o15) _(o16) _(o17) \ |
| 104 | _(S) _(D) _(o22) _(o23) _(W) _(L) _(o26) _(o27) \ |
| 105 | _(o30) _(o31) _(o32) _(o33) _(o34) _(o35) _(o36) _(o37) |
| 106 | |
| 107 | /* COP1 encoding of funct for S and D */ |
| 108 | #define mips_foreach_cop1_funct \ |
| 109 | _(add) _(sub) _(mul) _(div) _(sqrt) _(abs) _(mov) _(neg) \ |
| 110 | _(roundl) _(truncl) _(ceill) _(floorl) _(roundw) _(truncw) _(ceilw) _(floorw) \ |
| 111 | _(o20) _(MOVCF) _(movz) _(movn) _(o24) _(recip) _(rsqrt) _(o27) \ |
| 112 | _(o30) _(o31) _(o32) _(o33) _(o34) _(o35) _(o36) _(o37) \ |
| 113 | _(cvts) _(cvtd) _(o42) _(o43) _(cvtw) _(cvtl) _(o46) _(o47) \ |
| 114 | _(o50) _(o51) _(o52) _(o53) _(o54) _(o55) _(o56) _(o57) \ |
| 115 | _(cf) _(cun) _(ceq) _(cueq) _(colt) _(cult) _(cole) _(cule) \ |
| 116 | _(csf) _(cngle) _(cseq) _(cngl) _(clt) _(cnge) _(cle) _(cngt) |
| 117 | |
| 118 | /* COP1X encoding of funct */ |
| 119 | #define mips_foreach_cop1x_funct \ |
| 120 | _(lwxc1) _(ldxc1) _(o02) _(o03) _(o04) _(luxc1) _(o06) _(o07) \ |
| 121 | _(swxc1) _(sdxc1) _(o12) _(o13) _(o14) _(suxc1) _(o16) _(prefx) \ |
| 122 | _(o20) _(o21) _(o22) _(o23) _(o24) _(o25) _(o26) _(o27) \ |
| 123 | _(o30) _(o31) _(o32) _(o33) _(o34) _(o35) _(o36) _(o37) \ |
| 124 | _(madds) _(maddd) _(o42) _(o43) _(o44) _(o45) _(o46) _(o47) \ |
| 125 | _(msubs) _(msubd) _(o52) _(o53) _(o54) _(o55) _(o56) _(o57) \ |
| 126 | _(nmadds) _(nmaddd) _(o62) _(o63) _(o64) _(o65) _(o66) _(o67) \ |
| 127 | _(nmsubs) _(nmsubd) _(o72) _(o73) _(o74) _(o75) _(o76) _(o77) |
| 128 | |
| 129 | #define mips_foreach_mdmx_funct \ |
| 130 | _(msgn) _(ceq) _(pickf) _(pickt) _(clt) _(cle) _(min) _(max) \ |
| 131 | _(o10) _(o11) _(sub) _(add) _(and) _(xor) _(or) _(nor) \ |
| 132 | _(sll) _(o21) _(srl) _(sra) _(o24) _(o25) _(o26) _(o27) \ |
| 133 | _(alniob) _(alnvob) _(alniqh) _(alnvqh) _(o34) _(o35) _(o36) _(shfl) \ |
| 134 | _(rzu) _(rnau) _(rneu) _(o43) _(rzs) _(rnas) _(rnes) _(o47) \ |
| 135 | _(o50) _(o51) _(o52) _(o53) _(o54) _(o55) _(o56) _(o57) \ |
| 136 | _(mul) _(o61) _(muls) _(mula) _(o64) _(o65) _(suba) _(adda) \ |
| 137 | _(o70) _(o71) _(o72) _(o73) _(o74) _(o75) _(wac) _(rac) |
| 138 | |
| 139 | #define _(f) MIPS_OPCODE_##f, |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 140 | typedef enum |
| 141 | { |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 142 | mips_foreach_opcode |
| 143 | } mips_insn_opcode_t; |
| 144 | #undef _ |
| 145 | |
| 146 | #define _(f) MIPS_SPECIAL_FUNCT_##f, |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 147 | typedef enum |
| 148 | { |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 149 | mips_foreach_special_funct |
| 150 | } mips_insn_special_funct_t; |
| 151 | #undef _ |
| 152 | |
| 153 | #define _(f) MIPS_SPECIAL2_FUNCT_##f, |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 154 | typedef enum |
| 155 | { |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 156 | mips_foreach_special2_funct |
| 157 | } mips_insn_special2_funct_t; |
| 158 | #undef _ |
| 159 | |
| 160 | #define _(f) MIPS_REGIMM_RT_##f, |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 161 | typedef enum |
| 162 | { |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 163 | mips_foreach_regimm_rt |
| 164 | } mips_insn_regimm_rt_t; |
| 165 | #undef _ |
| 166 | |
| 167 | #define _(f) MIPS_COP0_RS_##f, |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 168 | typedef enum |
| 169 | { |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 170 | mips_foreach_cop0_rs |
| 171 | } mips_insn_cop0_rs_t; |
| 172 | #undef _ |
| 173 | |
| 174 | #define _(f) MIPS_COP0_FUNCT_##f, |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 175 | typedef enum |
| 176 | { |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 177 | mips_foreach_cop0_funct |
| 178 | } mips_insn_cop0_funct_t; |
| 179 | #undef _ |
| 180 | |
| 181 | #define _(f) MIPS_COP1_RS_##f, |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 182 | typedef enum |
| 183 | { |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 184 | mips_foreach_cop1_rs |
| 185 | } mips_insn_cop1_rs_t; |
| 186 | #undef _ |
| 187 | |
| 188 | #define _(f) MIPS_COP1_FUNCT_##f, |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 189 | typedef enum |
| 190 | { |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 191 | mips_foreach_cop1_funct |
| 192 | } mips_insn_cop1_funct_t; |
| 193 | #undef _ |
| 194 | |
| 195 | #define _(f) MIPS_COP1X_FUNCT_##f, |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 196 | typedef enum |
| 197 | { |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 198 | mips_foreach_cop1x_funct |
| 199 | } mips_insn_cop1x_funct_t; |
| 200 | #undef _ |
| 201 | |
| 202 | #define _(f) MIPS_MDMX_FUNCT_##f, |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 203 | typedef enum |
| 204 | { |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 205 | mips_foreach_mdmx_funct |
| 206 | } mips_insn_mdmx_funct_t; |
| 207 | #undef _ |
| 208 | |
| 209 | always_inline mips_insn_opcode_t |
| 210 | mips_insn_get_op (u32 insn) |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 211 | { |
| 212 | return (insn >> 26) & 0x3f; |
| 213 | } |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 214 | |
| 215 | always_inline u32 |
| 216 | mips_insn_get_rs (u32 insn) |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 217 | { |
| 218 | return (insn >> 21) & 0x1f; |
| 219 | } |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 220 | |
| 221 | always_inline u32 |
| 222 | mips_insn_get_rt (u32 insn) |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 223 | { |
| 224 | return (insn >> 16) & 0x1f; |
| 225 | } |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 226 | |
| 227 | always_inline u32 |
| 228 | mips_insn_get_rd (u32 insn) |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 229 | { |
| 230 | return (insn >> 11) & 0x1f; |
| 231 | } |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 232 | |
| 233 | always_inline u32 |
| 234 | mips_insn_get_sa (u32 insn) |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 235 | { |
| 236 | return (insn >> 6) & 0x1f; |
| 237 | } |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 238 | |
| 239 | always_inline u32 |
| 240 | mips_insn_get_funct (u32 insn) |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 241 | { |
| 242 | return (insn >> 0) & 0x3f; |
| 243 | } |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 244 | |
| 245 | always_inline i32 |
| 246 | mips_insn_get_immediate (u32 insn) |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 247 | { |
| 248 | return (((i32) insn) << 16) >> 16; |
| 249 | } |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 250 | |
| 251 | always_inline u32 |
| 252 | mips_insn_encode_i_type (int op, int rs, int rt, int immediate) |
| 253 | { |
| 254 | u32 insn; |
| 255 | insn = immediate; |
| 256 | insn |= rt << 16; |
| 257 | insn |= rs << 21; |
| 258 | insn |= op << 26; |
| 259 | |
| 260 | ASSERT (mips_insn_get_immediate (insn) == immediate); |
| 261 | ASSERT (mips_insn_get_rt (insn) == rt); |
| 262 | ASSERT (mips_insn_get_rs (insn) == rt); |
| 263 | ASSERT (mips_insn_get_op (insn) == op); |
| 264 | |
| 265 | return insn; |
| 266 | } |
| 267 | |
| 268 | always_inline u32 |
| 269 | mips_insn_encode_j_type (int op, u32 addr) |
| 270 | { |
| 271 | u32 insn; |
| 272 | |
| 273 | insn = (addr & ((1 << 28) - 1)) / 4; |
| 274 | insn |= op << 26; |
| 275 | |
| 276 | return insn; |
| 277 | } |
| 278 | |
| 279 | always_inline u32 |
| 280 | mips_insn_encode_r_type (int op, int rs, int rt, int rd, int sa, int funct) |
| 281 | { |
| 282 | u32 insn; |
| 283 | insn = funct; |
| 284 | insn |= sa << 6; |
| 285 | insn |= rd << 11; |
| 286 | insn |= rt << 16; |
| 287 | insn |= rs << 21; |
| 288 | insn |= op << 26; |
| 289 | |
| 290 | ASSERT (mips_insn_get_funct (insn) == funct); |
| 291 | ASSERT (mips_insn_get_sa (insn) == sa); |
| 292 | ASSERT (mips_insn_get_rd (insn) == rd); |
| 293 | ASSERT (mips_insn_get_rt (insn) == rt); |
| 294 | ASSERT (mips_insn_get_rs (insn) == rt); |
| 295 | ASSERT (mips_insn_get_op (insn) == op); |
| 296 | |
| 297 | return insn; |
| 298 | } |
| 299 | |
| 300 | #define mips_insn_r(op,funct,rd,rs,rt,sa) \ |
| 301 | mips_insn_encode_r_type (MIPS_OPCODE_##op, \ |
| 302 | (rs), (rt), (rd), (sa), \ |
| 303 | MIPS_##op##_FUNCT_##funct) |
| 304 | |
| 305 | #define mips_insn_i(op,rs,rt,imm) \ |
| 306 | mips_insn_encode_i_type (MIPS_OPCODE_##op, (rs), (rt), (imm)) |
| 307 | |
| 308 | #define mips_insn_j(op,target) \ |
| 309 | mips_insn_encode_i_type (MIPS_OPCODE_##op, (rs), (rt), (imm)) |
| 310 | |
| 311 | /* Generate unsigned load instructions of data of various sizes. */ |
| 312 | always_inline u32 |
| 313 | mips_insn_load (u32 rd, i32 offset, u32 base, u32 log2_bytes) |
| 314 | { |
| 315 | int op; |
| 316 | |
| 317 | ASSERT (log2_bytes < 4); |
| 318 | switch (log2_bytes) |
| 319 | { |
| 320 | case 0: |
| 321 | op = MIPS_OPCODE_lbu; |
| 322 | break; |
| 323 | case 1: |
| 324 | op = MIPS_OPCODE_lhu; |
| 325 | break; |
| 326 | case 2: |
| 327 | op = MIPS_OPCODE_lwu; |
| 328 | break; |
| 329 | case 3: |
| 330 | op = MIPS_OPCODE_ld; |
| 331 | break; |
| 332 | } |
| 333 | |
| 334 | return mips_insn_encode_i_type (op, base, rd, offset); |
| 335 | } |
| 336 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 337 | typedef enum |
| 338 | { |
| 339 | MIPS_REG_SP = 29, |
| 340 | MIPS_REG_RA = 31, |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 341 | } mips_reg_t; |
| 342 | |
| 343 | #endif /* included_asm_mips_h */ |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 344 | |
| 345 | /* |
| 346 | * fd.io coding-style-patch-verification: ON |
| 347 | * |
| 348 | * Local Variables: |
| 349 | * eval: (c-set-style "gnu") |
| 350 | * End: |
| 351 | */ |