1// -*- C -*- 2 3// Simulator definition for the MIPS16e instructions. 4// Copyright (C) 2005-2024 Free Software Foundation, Inc. 5// Contributed by Nigel Stephens (nigel@mips.com) and 6// David Ung (davidu@mips.com) of MIPS Technologies. 7// 8// This file is part of GDB, the GNU debugger. 9// 10// This program is free software; you can redistribute it and/or modify 11// it under the terms of the GNU General Public License as published by 12// the Free Software Foundation; either version 3 of the License, or 13// (at your option) any later version. 14// 15// This program is distributed in the hope that it will be useful, 16// but WITHOUT ANY WARRANTY; without even the implied warranty of 17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18// GNU General Public License for more details. 19// 20// You should have received a copy of the GNU General Public License 21// along with this program. If not, see <http://www.gnu.org/licenses/>. 22 23 2411101,3.RX,100,10001:RR:16::SEB 25"seb r<TRX>" 26*mips16e: 27{ 28 TRACE_ALU_INPUT1 (GPR[TRX]); 29 GPR[TRX] = EXTEND8 (GPR[TRX]); 30 TRACE_ALU_RESULT (GPR[TRX]); 31} 32 33 3411101,3.RX,101,10001:RR:16::SEH 35"seh r<TRX>" 36*mips16e: 37{ 38 TRACE_ALU_INPUT1 (GPR[TRX]); 39 GPR[TRX] = EXTEND16 (GPR[TRX]); 40 TRACE_ALU_RESULT (GPR[TRX]); 41} 42 4311101,3.RX,110,10001:RR:16::SEW 44"sew r<TRX>" 45*mips16e: 46{ 47 check_u64 (SD_, instruction_0); 48 TRACE_ALU_INPUT1 (GPR[TRX]); 49 GPR[TRX] = EXTEND32 (GPR[TRX]); 50 TRACE_ALU_RESULT (GPR[TRX]); 51} 52 5311101,3.RX,000,10001:RR:16::ZEB 54"zeb r<TRX>" 55*mips16e: 56{ 57 TRACE_ALU_INPUT1 (GPR[TRX]); 58 GPR[TRX] = (unsigned_word)(uint8_t)(GPR[TRX]); 59 TRACE_ALU_RESULT (GPR[TRX]); 60} 61 6211101,3.RX,001,10001:RR:16::ZEH 63"zeh r<TRX>" 64*mips16e: 65{ 66 TRACE_ALU_INPUT1 (GPR[TRX]); 67 GPR[TRX] = (unsigned_word)(uint16_t)(GPR[TRX]); 68 TRACE_ALU_RESULT (GPR[TRX]); 69} 70 7111101,3.RX,010,10001:RR:16::ZEW 72"zew r<TRX>" 73*mips16e: 74{ 75 check_u64 (SD_, instruction_0); 76 TRACE_ALU_INPUT1 (GPR[TRX]); 77 GPR[TRX] = (unsigned_word)(uint32_t)(GPR[TRX]); 78 TRACE_ALU_RESULT (GPR[TRX]); 79} 80 81 8211101,3.RX,100,00000:RR:16::JRC 83"jrc r<TRX>" 84*mips16e: 85{ 86 NIA = GPR[TRX]; 87} 88 89 9011101,000,101,00000:RR:16::JRCRA 91"jrc ra" 92*mips16e: 93{ 94 NIA = RA; 95} 96 97 9811101,3.RX,110,00000:RR:16::JALRC 99"jalrc r<TRX>" 100*mips16e: 101{ 102 RA = NIA; 103 NIA = GPR[TRX]; 104} 105 106 107// format routines for save/restore 108:%s::::RAS:int ras 109*mips16e 110{ 111 static char buf[10]; 112 buf[0] = '\0'; 113 if (ras & 4) 114 strcat (buf,"ra,"); 115 if (ras & 2) 116 strcat (buf,"s0,"); 117 if (ras & 1) 118 strcat (buf,"s1,"); 119 return (buf); 120} 121 122:%s::::XSREGS:int xsregs 123*mips16e 124{ 125 if (xsregs > 6) 126 return "s2,s3,s4,s5,s6,s7,s8,"; 127 if (xsregs > 5) 128 return "s2,s3,s4,s5,s6,s7,"; 129 if (xsregs > 4) 130 return "s2,s3,s4,s5,s6,"; 131 if (xsregs > 3) 132 return "s2,s3,s4,s5,"; 133 if (xsregs > 2) 134 return "s2,s3,s4,"; 135 if (xsregs > 1) 136 return "s2,s3,"; 137 if (xsregs > 0) 138 return "s2,"; 139 return ""; 140} 141 142:%s::::AREGS:int aregs 143*mips16e 144{ 145 // Fixme: how is the arg/static distinction made by the assembler? 146 static const char * const aregstr[16] = { 147 "", 148 "A3,", 149 "A2,A3,", 150 "A1,A2,A3,", 151 "A0,A1,A2,A3,", 152 "a0,", 153 "a0,A3,", 154 "a0,A2,A3,", 155 "a0,A1,A2,A3,", 156 "a0,a1,", 157 "a0,a1,A3,", 158 "a0,a1,A2,A3,", 159 "a0,a1,a2,", 160 "a0,a1,a2,A3,", 161 "?," 162 }; 163 return aregstr[aregs]; 164} 165 166:compute:::int:SFRAME:FS:((FS == 0) ? 128 \: (FS << 3)) 167:compute:::int:BFRAME:FSHI,FSLO:(((FSHI << 4) | FSLO) << 3) 168 169:function:::void:do_save:int xsregs, int aregs, int ras0s1, int framesize 170{ 171 unsigned_word temp; 172 int args, astatic; 173 174 temp = GPR[29]; 175 176 /* writes are in the same order as the hardware description... */ 177 switch (aregs) { 178 case 0: case 1: case 2: case 3: case 11: 179 args = 0; 180 break; 181 case 4: case 5: case 6: case 7: 182 args = 1; 183 break; 184 case 8: case 9: case 10: 185 args = 2; 186 break; 187 case 12: case 13: 188 args = 3; 189 break; 190 case 14: 191 args = 4; 192 break; 193 default: 194 sim_engine_abort (SD, CPU, CIA, "save: aregs=%d causes unpredictable results\n", aregs); 195 } 196 if (args > 0) { 197 do_store (SD_, AccessLength_WORD, temp, 0, GPR[4]); 198 if (args > 1) { 199 do_store (SD_,AccessLength_WORD, temp, 4 , GPR[5]); 200 if (args > 2) { 201 do_store (SD_,AccessLength_WORD, temp, 8 , GPR[6]); 202 if (args > 3) { 203 do_store (SD_,AccessLength_WORD, temp, 12, GPR[7]); 204 } 205 } 206 } 207 } 208 209 if (ras0s1 & 4) 210 do_store (SD_,AccessLength_WORD, temp -= 4, 0, GPR[31]); 211 212 switch (xsregs) { 213 case 7: 214 do_store (SD_,AccessLength_WORD, temp -= 4, 0, GPR[30]); 215 ATTRIBUTE_FALLTHROUGH; 216 case 6: 217 do_store (SD_,AccessLength_WORD, temp -= 4, 0, GPR[23]); 218 ATTRIBUTE_FALLTHROUGH; 219 case 5: 220 do_store (SD_,AccessLength_WORD, temp -= 4, 0, GPR[22]); 221 ATTRIBUTE_FALLTHROUGH; 222 case 4: 223 do_store (SD_,AccessLength_WORD, temp -= 4, 0, GPR[21]); 224 ATTRIBUTE_FALLTHROUGH; 225 case 3: 226 do_store (SD_,AccessLength_WORD, temp -= 4, 0, GPR[20]); 227 ATTRIBUTE_FALLTHROUGH; 228 case 2: 229 do_store (SD_,AccessLength_WORD, temp -= 4, 0, GPR[19]); 230 ATTRIBUTE_FALLTHROUGH; 231 case 1: 232 do_store (SD_,AccessLength_WORD, temp -= 4, 0, GPR[18]); 233 } 234 235 if (ras0s1 & 1) 236 do_store (SD_,AccessLength_WORD, temp -= 4, 0, GPR[17]); 237 if (ras0s1 & 2) 238 do_store (SD_,AccessLength_WORD, temp -= 4, 0, GPR[16]); 239 240 switch (aregs) { 241 case 0: case 4: case 8: case 12: case 14: 242 astatic = 0; 243 break; 244 case 1: case 5: case 9: case 13: 245 astatic = 1; 246 break; 247 case 2: case 6: case 10: 248 astatic = 2; 249 break; 250 case 3: case 7: 251 astatic = 3; 252 break; 253 case 11: 254 astatic = 4; 255 break; 256 default: 257 sim_engine_abort (SD, CPU, CIA, "save: aregs=%d causes unpredictable results\n", aregs); 258 } 259 if (astatic > 0) { 260 do_store (SD_, AccessLength_WORD, temp -= 4, 0, GPR[7]); 261 if (astatic > 1) { 262 do_store (SD_, AccessLength_WORD, temp -= 4, 0, GPR[6]); 263 if (astatic > 2) { 264 do_store (SD_, AccessLength_WORD, temp -= 4, 0, GPR[5]); 265 if (astatic > 3) { 266 do_store (SD_, AccessLength_WORD, temp -= 4, 0, GPR[4]); 267 } 268 } 269 } 270 } 271 272 GPR[29] -= framesize; 273} 274 27501100,100,1,3.RAS,4.FS:I8:16::SAVE 276"save %s<RAS>,<SFRAME>" 277*mips16e 278{ 279 do_save (SD_, 0, 0, RAS, SFRAME); 280} 281 282 28311110,3.XSREGS,4.FSHI,4.AREGS + 01100,100,1,3.RAS,4.FSLO:EXT-I8:16::SAVE 284"save %s<RAS>%s<XSREGS>%s<AREGS><BFRAME>" 285*mips16e 286{ 287 do_save (SD_, XSREGS, AREGS, RAS, BFRAME); 288} 289 290 291:function:::void:do_restore:int xsregs, int aregs, int ras0s1, int framesize 292*mips16e 293{ 294 unsigned_word temp, temp2; 295 int astatic; 296 297 temp = GPR[29] + framesize; 298 temp2 = temp; 299 300 /* reads are in the same order as the hardware description... */ 301 302 if (ras0s1 & 4) 303 GPR[31] = EXTEND32 (do_load(SD_, AccessLength_WORD, temp -= 4, 0)); 304 305 switch (xsregs) { 306 case 7: 307 GPR[30] = EXTEND32 (do_load (SD_,AccessLength_WORD, temp -= 4, 0)); 308 case 6: 309 GPR[23] = EXTEND32 (do_load (SD_,AccessLength_WORD, temp -= 4, 0)); 310 case 5: 311 GPR[22] = EXTEND32 (do_load (SD_,AccessLength_WORD, temp -= 4, 0)); 312 case 4: 313 GPR[21] = EXTEND32 (do_load (SD_,AccessLength_WORD, temp -= 4, 0)); 314 case 3: 315 GPR[20] = EXTEND32 (do_load (SD_,AccessLength_WORD, temp -= 4, 0)); 316 case 2: 317 GPR[19] = EXTEND32 (do_load (SD_,AccessLength_WORD, temp -= 4, 0)); 318 case 1: 319 GPR[18] = EXTEND32 (do_load (SD_,AccessLength_WORD, temp -= 4, 0)); 320 } 321 322 if (ras0s1 & 1) 323 GPR[17] = EXTEND32 (do_load (SD_,AccessLength_WORD, temp -= 4, 0)); 324 if (ras0s1 & 2) 325 GPR[16] = EXTEND32 (do_load (SD_,AccessLength_WORD, temp -= 4, 0)); 326 327 switch (aregs) { 328 case 0: case 4: case 8: case 12: case 14: 329 astatic = 0; 330 break; 331 case 1: case 5: case 9: case 13: 332 astatic = 1; 333 break; 334 case 2: case 6: case 10: 335 astatic = 2; 336 break; 337 case 3: case 7: 338 astatic = 3; 339 break; 340 case 11: 341 astatic = 4; 342 break; 343 default: 344 sim_engine_abort (SD, CPU, CIA, "save: aregs=%d causes unpredictable results\n", aregs); 345 } 346 if (astatic > 0) { 347 GPR[7] = EXTEND32 (do_load (SD_,AccessLength_WORD, temp -= 4, 0)); 348 if (astatic > 1) { 349 GPR[6] = EXTEND32 (do_load (SD_,AccessLength_WORD, temp -= 4, 0)); 350 if (astatic > 2) { 351 GPR[5] = EXTEND32 (do_load (SD_,AccessLength_WORD, temp -= 4, 0)); 352 if (astatic > 3) { 353 GPR[4] = EXTEND32 (do_load (SD_,AccessLength_WORD, temp -= 4, 0)); 354 } 355 } 356 } 357 } 358 359 GPR[29] = temp2; 360} 361 36201100,100,0,3.RAS,4.FS:I8:16::RESTORE 363"restore %s<RAS>,<SFRAME>" 364*mips16e 365{ 366 do_restore (SD_,0,0,RAS,SFRAME); 367} 368 36911110,3.XSREGS,4.FSHI,4.AREGS + 01100,100,0,3.RAS,4.FSLO:EXT-I8:16::RESTORE 370"restore %s<RAS>%s<XSREGS>%s<AREGS><BFRAME>" 371*mips16e 372{ 373 do_restore (SD_,XSREGS,AREGS,RAS,BFRAME); 374} 375