1 /* 2 * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #ifndef HEXAGON_GEN_TCG_H 19 #define HEXAGON_GEN_TCG_H 20 21 /* 22 * Here is a primer to understand the tag names for load/store instructions 23 * 24 * Data types 25 * b signed byte r0 = memb(r2+#0) 26 * ub unsigned byte r0 = memub(r2+#0) 27 * h signed half word (16 bits) r0 = memh(r2+#0) 28 * uh unsigned half word r0 = memuh(r2+#0) 29 * i integer (32 bits) r0 = memw(r2+#0) 30 * d double word (64 bits) r1:0 = memd(r2+#0) 31 * 32 * Addressing modes 33 * _io indirect with offset r0 = memw(r1+#4) 34 * _ur absolute with register offset r0 = memw(r1<<#4+##variable) 35 * _rr indirect with register offset r0 = memw(r1+r4<<#2) 36 * gp global pointer relative r0 = memw(gp+#200) 37 * _sp stack pointer relative r0 = memw(r29+#12) 38 * _ap absolute set r0 = memw(r1=##variable) 39 * _pr post increment register r0 = memw(r1++m1) 40 * _pi post increment immediate r0 = memb(r1++#1) 41 */ 42 43 /* Macros for complex addressing modes */ 44 #define GET_EA_ap \ 45 do { \ 46 fEA_IMM(UiV); \ 47 tcg_gen_movi_tl(ReV, UiV); \ 48 } while (0) 49 #define GET_EA_pr \ 50 do { \ 51 fEA_REG(RxV); \ 52 fPM_M(RxV, MuV); \ 53 } while (0) 54 #define GET_EA_pi \ 55 do { \ 56 fEA_REG(RxV); \ 57 fPM_I(RxV, siV); \ 58 } while (0) 59 60 61 /* Instructions with multiple definitions */ 62 #define fGEN_TCG_LOAD_AP(RES, SIZE, SIGN) \ 63 do { \ 64 fMUST_IMMEXT(UiV); \ 65 fEA_IMM(UiV); \ 66 fLOAD(1, SIZE, SIGN, EA, RES); \ 67 tcg_gen_movi_tl(ReV, UiV); \ 68 } while (0) 69 70 #define fGEN_TCG_L4_loadrub_ap(SHORTCODE) \ 71 fGEN_TCG_LOAD_AP(RdV, 1, u) 72 #define fGEN_TCG_L4_loadrb_ap(SHORTCODE) \ 73 fGEN_TCG_LOAD_AP(RdV, 1, s) 74 #define fGEN_TCG_L4_loadruh_ap(SHORTCODE) \ 75 fGEN_TCG_LOAD_AP(RdV, 2, u) 76 #define fGEN_TCG_L4_loadrh_ap(SHORTCODE) \ 77 fGEN_TCG_LOAD_AP(RdV, 2, s) 78 #define fGEN_TCG_L4_loadri_ap(SHORTCODE) \ 79 fGEN_TCG_LOAD_AP(RdV, 4, u) 80 #define fGEN_TCG_L4_loadrd_ap(SHORTCODE) \ 81 fGEN_TCG_LOAD_AP(RddV, 8, u) 82 83 #define fGEN_TCG_L2_loadrub_pr(SHORTCODE) SHORTCODE 84 #define fGEN_TCG_L2_loadrub_pi(SHORTCODE) SHORTCODE 85 #define fGEN_TCG_L2_loadrb_pr(SHORTCODE) SHORTCODE 86 #define fGEN_TCG_L2_loadrb_pi(SHORTCODE) SHORTCODE; 87 #define fGEN_TCG_L2_loadruh_pr(SHORTCODE) SHORTCODE 88 #define fGEN_TCG_L2_loadruh_pi(SHORTCODE) SHORTCODE; 89 #define fGEN_TCG_L2_loadrh_pr(SHORTCODE) SHORTCODE 90 #define fGEN_TCG_L2_loadrh_pi(SHORTCODE) SHORTCODE 91 #define fGEN_TCG_L2_loadri_pr(SHORTCODE) SHORTCODE 92 #define fGEN_TCG_L2_loadri_pi(SHORTCODE) SHORTCODE 93 #define fGEN_TCG_L2_loadrd_pr(SHORTCODE) SHORTCODE 94 #define fGEN_TCG_L2_loadrd_pi(SHORTCODE) SHORTCODE 95 96 /* 97 * Predicated loads 98 * Here is a primer to understand the tag names 99 * 100 * Predicate used 101 * t true "old" value if (p0) r0 = memb(r2+#0) 102 * f false "old" value if (!p0) r0 = memb(r2+#0) 103 * tnew true "new" value if (p0.new) r0 = memb(r2+#0) 104 * fnew false "new" value if (!p0.new) r0 = memb(r2+#0) 105 */ 106 #define fGEN_TCG_PRED_LOAD(GET_EA, PRED, SIZE, SIGN) \ 107 do { \ 108 TCGv LSB = tcg_temp_local_new(); \ 109 TCGLabel *label = gen_new_label(); \ 110 GET_EA; \ 111 PRED; \ 112 PRED_LOAD_CANCEL(LSB, EA); \ 113 tcg_gen_movi_tl(RdV, 0); \ 114 tcg_gen_brcondi_tl(TCG_COND_EQ, LSB, 0, label); \ 115 fLOAD(1, SIZE, SIGN, EA, RdV); \ 116 gen_set_label(label); \ 117 tcg_temp_free(LSB); \ 118 } while (0) 119 120 #define fGEN_TCG_L2_ploadrubt_pi(SHORTCODE) \ 121 fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBOLD(PtV), 1, u) 122 #define fGEN_TCG_L2_ploadrubf_pi(SHORTCODE) \ 123 fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBOLDNOT(PtV), 1, u) 124 #define fGEN_TCG_L2_ploadrubtnew_pi(SHORTCODE) \ 125 fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBNEW(PtN), 1, u) 126 #define fGEN_TCG_L2_ploadrubfnew_pi(SHORTCODE) \ 127 fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBNEWNOT(PtN), 1, u) 128 #define fGEN_TCG_L2_ploadrbt_pi(SHORTCODE) \ 129 fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBOLD(PtV), 1, s) 130 #define fGEN_TCG_L2_ploadrbf_pi(SHORTCODE) \ 131 fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBOLDNOT(PtV), 1, s) 132 #define fGEN_TCG_L2_ploadrbtnew_pi(SHORTCODE) \ 133 fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBNEW(PtN), 1, s) 134 #define fGEN_TCG_L2_ploadrbfnew_pi(SHORTCODE) \ 135 fGEN_TCG_PRED_LOAD({ fEA_REG(RxV); fPM_I(RxV, siV); }, \ 136 fLSBNEWNOT(PtN), 1, s) 137 138 #define fGEN_TCG_L2_ploadruht_pi(SHORTCODE) \ 139 fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBOLD(PtV), 2, u) 140 #define fGEN_TCG_L2_ploadruhf_pi(SHORTCODE) \ 141 fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBOLDNOT(PtV), 2, u) 142 #define fGEN_TCG_L2_ploadruhtnew_pi(SHORTCODE) \ 143 fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBNEW(PtN), 2, u) 144 #define fGEN_TCG_L2_ploadruhfnew_pi(SHORTCODE) \ 145 fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBNEWNOT(PtN), 2, u) 146 #define fGEN_TCG_L2_ploadrht_pi(SHORTCODE) \ 147 fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBOLD(PtV), 2, s) 148 #define fGEN_TCG_L2_ploadrhf_pi(SHORTCODE) \ 149 fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBOLDNOT(PtV), 2, s) 150 #define fGEN_TCG_L2_ploadrhtnew_pi(SHORTCODE) \ 151 fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBNEW(PtN), 2, s) 152 #define fGEN_TCG_L2_ploadrhfnew_pi(SHORTCODE) \ 153 fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBNEWNOT(PtN), 2, s) 154 155 #define fGEN_TCG_L2_ploadrit_pi(SHORTCODE) \ 156 fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBOLD(PtV), 4, u) 157 #define fGEN_TCG_L2_ploadrif_pi(SHORTCODE) \ 158 fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBOLDNOT(PtV), 4, u) 159 #define fGEN_TCG_L2_ploadritnew_pi(SHORTCODE) \ 160 fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBNEW(PtN), 4, u) 161 #define fGEN_TCG_L2_ploadrifnew_pi(SHORTCODE) \ 162 fGEN_TCG_PRED_LOAD(GET_EA_pi, fLSBNEWNOT(PtN), 4, u) 163 164 /* Predicated loads into a register pair */ 165 #define fGEN_TCG_PRED_LOAD_PAIR(GET_EA, PRED) \ 166 do { \ 167 TCGv LSB = tcg_temp_local_new(); \ 168 TCGLabel *label = gen_new_label(); \ 169 GET_EA; \ 170 PRED; \ 171 PRED_LOAD_CANCEL(LSB, EA); \ 172 tcg_gen_movi_i64(RddV, 0); \ 173 tcg_gen_brcondi_tl(TCG_COND_EQ, LSB, 0, label); \ 174 fLOAD(1, 8, u, EA, RddV); \ 175 gen_set_label(label); \ 176 tcg_temp_free(LSB); \ 177 } while (0) 178 179 #define fGEN_TCG_L2_ploadrdt_pi(SHORTCODE) \ 180 fGEN_TCG_PRED_LOAD_PAIR(GET_EA_pi, fLSBOLD(PtV)) 181 #define fGEN_TCG_L2_ploadrdf_pi(SHORTCODE) \ 182 fGEN_TCG_PRED_LOAD_PAIR(GET_EA_pi, fLSBOLDNOT(PtV)) 183 #define fGEN_TCG_L2_ploadrdtnew_pi(SHORTCODE) \ 184 fGEN_TCG_PRED_LOAD_PAIR(GET_EA_pi, fLSBNEW(PtN)) 185 #define fGEN_TCG_L2_ploadrdfnew_pi(SHORTCODE) \ 186 fGEN_TCG_PRED_LOAD_PAIR(GET_EA_pi, fLSBNEWNOT(PtN)) 187 188 /* load-locked and store-locked */ 189 #define fGEN_TCG_L2_loadw_locked(SHORTCODE) \ 190 SHORTCODE 191 #define fGEN_TCG_L4_loadd_locked(SHORTCODE) \ 192 SHORTCODE 193 #define fGEN_TCG_S2_storew_locked(SHORTCODE) \ 194 do { SHORTCODE; READ_PREG(PdV, PdN); } while (0) 195 #define fGEN_TCG_S4_stored_locked(SHORTCODE) \ 196 do { SHORTCODE; READ_PREG(PdV, PdN); } while (0) 197 198 /* Floating point */ 199 #define fGEN_TCG_F2_conv_sf2df(SHORTCODE) \ 200 gen_helper_conv_sf2df(RddV, cpu_env, RsV) 201 #define fGEN_TCG_F2_conv_df2sf(SHORTCODE) \ 202 gen_helper_conv_df2sf(RdV, cpu_env, RssV) 203 #define fGEN_TCG_F2_conv_uw2sf(SHORTCODE) \ 204 gen_helper_conv_uw2sf(RdV, cpu_env, RsV) 205 #define fGEN_TCG_F2_conv_uw2df(SHORTCODE) \ 206 gen_helper_conv_uw2df(RddV, cpu_env, RsV) 207 #define fGEN_TCG_F2_conv_w2sf(SHORTCODE) \ 208 gen_helper_conv_w2sf(RdV, cpu_env, RsV) 209 #define fGEN_TCG_F2_conv_w2df(SHORTCODE) \ 210 gen_helper_conv_w2df(RddV, cpu_env, RsV) 211 #define fGEN_TCG_F2_conv_ud2sf(SHORTCODE) \ 212 gen_helper_conv_ud2sf(RdV, cpu_env, RssV) 213 #define fGEN_TCG_F2_conv_ud2df(SHORTCODE) \ 214 gen_helper_conv_ud2df(RddV, cpu_env, RssV) 215 #define fGEN_TCG_F2_conv_d2sf(SHORTCODE) \ 216 gen_helper_conv_d2sf(RdV, cpu_env, RssV) 217 #define fGEN_TCG_F2_conv_d2df(SHORTCODE) \ 218 gen_helper_conv_d2df(RddV, cpu_env, RssV) 219 #define fGEN_TCG_F2_conv_sf2uw(SHORTCODE) \ 220 gen_helper_conv_sf2uw(RdV, cpu_env, RsV) 221 #define fGEN_TCG_F2_conv_sf2w(SHORTCODE) \ 222 gen_helper_conv_sf2w(RdV, cpu_env, RsV) 223 #define fGEN_TCG_F2_conv_sf2ud(SHORTCODE) \ 224 gen_helper_conv_sf2ud(RddV, cpu_env, RsV) 225 #define fGEN_TCG_F2_conv_sf2d(SHORTCODE) \ 226 gen_helper_conv_sf2d(RddV, cpu_env, RsV) 227 #define fGEN_TCG_F2_conv_df2uw(SHORTCODE) \ 228 gen_helper_conv_df2uw(RdV, cpu_env, RssV) 229 #define fGEN_TCG_F2_conv_df2w(SHORTCODE) \ 230 gen_helper_conv_df2w(RdV, cpu_env, RssV) 231 #define fGEN_TCG_F2_conv_df2ud(SHORTCODE) \ 232 gen_helper_conv_df2ud(RddV, cpu_env, RssV) 233 #define fGEN_TCG_F2_conv_df2d(SHORTCODE) \ 234 gen_helper_conv_df2d(RddV, cpu_env, RssV) 235 #define fGEN_TCG_F2_conv_sf2uw_chop(SHORTCODE) \ 236 gen_helper_conv_sf2uw_chop(RdV, cpu_env, RsV) 237 #define fGEN_TCG_F2_conv_sf2w_chop(SHORTCODE) \ 238 gen_helper_conv_sf2w_chop(RdV, cpu_env, RsV) 239 #define fGEN_TCG_F2_conv_sf2ud_chop(SHORTCODE) \ 240 gen_helper_conv_sf2ud_chop(RddV, cpu_env, RsV) 241 #define fGEN_TCG_F2_conv_sf2d_chop(SHORTCODE) \ 242 gen_helper_conv_sf2d_chop(RddV, cpu_env, RsV) 243 #define fGEN_TCG_F2_conv_df2uw_chop(SHORTCODE) \ 244 gen_helper_conv_df2uw_chop(RdV, cpu_env, RssV) 245 #define fGEN_TCG_F2_conv_df2w_chop(SHORTCODE) \ 246 gen_helper_conv_df2w_chop(RdV, cpu_env, RssV) 247 #define fGEN_TCG_F2_conv_df2ud_chop(SHORTCODE) \ 248 gen_helper_conv_df2ud_chop(RddV, cpu_env, RssV) 249 #define fGEN_TCG_F2_conv_df2d_chop(SHORTCODE) \ 250 gen_helper_conv_df2d_chop(RddV, cpu_env, RssV) 251 #define fGEN_TCG_F2_sfadd(SHORTCODE) \ 252 gen_helper_sfadd(RdV, cpu_env, RsV, RtV) 253 #define fGEN_TCG_F2_sfsub(SHORTCODE) \ 254 gen_helper_sfsub(RdV, cpu_env, RsV, RtV) 255 #define fGEN_TCG_F2_sfcmpeq(SHORTCODE) \ 256 gen_helper_sfcmpeq(PdV, cpu_env, RsV, RtV) 257 #define fGEN_TCG_F2_sfcmpgt(SHORTCODE) \ 258 gen_helper_sfcmpgt(PdV, cpu_env, RsV, RtV) 259 #define fGEN_TCG_F2_sfcmpge(SHORTCODE) \ 260 gen_helper_sfcmpge(PdV, cpu_env, RsV, RtV) 261 #define fGEN_TCG_F2_sfcmpuo(SHORTCODE) \ 262 gen_helper_sfcmpuo(PdV, cpu_env, RsV, RtV) 263 #define fGEN_TCG_F2_sfmax(SHORTCODE) \ 264 gen_helper_sfmax(RdV, cpu_env, RsV, RtV) 265 #define fGEN_TCG_F2_sfmin(SHORTCODE) \ 266 gen_helper_sfmin(RdV, cpu_env, RsV, RtV) 267 #define fGEN_TCG_F2_sfclass(SHORTCODE) \ 268 do { \ 269 TCGv imm = tcg_const_tl(uiV); \ 270 gen_helper_sfclass(PdV, cpu_env, RsV, imm); \ 271 tcg_temp_free(imm); \ 272 } while (0) 273 #define fGEN_TCG_F2_sffixupn(SHORTCODE) \ 274 gen_helper_sffixupn(RdV, cpu_env, RsV, RtV) 275 #define fGEN_TCG_F2_sffixupd(SHORTCODE) \ 276 gen_helper_sffixupd(RdV, cpu_env, RsV, RtV) 277 #define fGEN_TCG_F2_sffixupr(SHORTCODE) \ 278 gen_helper_sffixupr(RdV, cpu_env, RsV) 279 #define fGEN_TCG_F2_dfadd(SHORTCODE) \ 280 gen_helper_dfadd(RddV, cpu_env, RssV, RttV) 281 #define fGEN_TCG_F2_dfsub(SHORTCODE) \ 282 gen_helper_dfsub(RddV, cpu_env, RssV, RttV) 283 #define fGEN_TCG_F2_dfmax(SHORTCODE) \ 284 gen_helper_dfmax(RddV, cpu_env, RssV, RttV) 285 #define fGEN_TCG_F2_dfmin(SHORTCODE) \ 286 gen_helper_dfmin(RddV, cpu_env, RssV, RttV) 287 #define fGEN_TCG_F2_dfcmpeq(SHORTCODE) \ 288 gen_helper_dfcmpeq(PdV, cpu_env, RssV, RttV) 289 #define fGEN_TCG_F2_dfcmpgt(SHORTCODE) \ 290 gen_helper_dfcmpgt(PdV, cpu_env, RssV, RttV) 291 #define fGEN_TCG_F2_dfcmpge(SHORTCODE) \ 292 gen_helper_dfcmpge(PdV, cpu_env, RssV, RttV) 293 #define fGEN_TCG_F2_dfcmpuo(SHORTCODE) \ 294 gen_helper_dfcmpuo(PdV, cpu_env, RssV, RttV) 295 #define fGEN_TCG_F2_dfclass(SHORTCODE) \ 296 do { \ 297 TCGv imm = tcg_const_tl(uiV); \ 298 gen_helper_dfclass(PdV, cpu_env, RssV, imm); \ 299 tcg_temp_free(imm); \ 300 } while (0) 301 #define fGEN_TCG_F2_sfmpy(SHORTCODE) \ 302 gen_helper_sfmpy(RdV, cpu_env, RsV, RtV) 303 #define fGEN_TCG_F2_sffma(SHORTCODE) \ 304 gen_helper_sffma(RxV, cpu_env, RxV, RsV, RtV) 305 #define fGEN_TCG_F2_sffma_sc(SHORTCODE) \ 306 gen_helper_sffma_sc(RxV, cpu_env, RxV, RsV, RtV, PuV) 307 #define fGEN_TCG_F2_sffms(SHORTCODE) \ 308 gen_helper_sffms(RxV, cpu_env, RxV, RsV, RtV) 309 #define fGEN_TCG_F2_sffma_lib(SHORTCODE) \ 310 gen_helper_sffma_lib(RxV, cpu_env, RxV, RsV, RtV) 311 #define fGEN_TCG_F2_sffms_lib(SHORTCODE) \ 312 gen_helper_sffms_lib(RxV, cpu_env, RxV, RsV, RtV) 313 314 #define fGEN_TCG_F2_dfmpyfix(SHORTCODE) \ 315 gen_helper_dfmpyfix(RddV, cpu_env, RssV, RttV) 316 #define fGEN_TCG_F2_dfmpyhh(SHORTCODE) \ 317 gen_helper_dfmpyhh(RxxV, cpu_env, RxxV, RssV, RttV) 318 319 #endif 320