1// -*- C -*- 2 3// Simulator definition for the Broadcom SiByte SB-1 CPU extensions. 4// Copyright (C) 2002-2024 Free Software Foundation, Inc. 5// Contributed by Ed Satterthwaite and Chris Demetriou, of Broadcom 6// Corporation (SiByte). 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 24// Helper: 25// 26// Check that the SB-1 extension instruction can currently be used, and 27// signal a ReservedInstruction exception if not. 28// 29 30:function:::void:check_sbx:instruction_word insn 31*sb1: 32{ 33 if ((SR & status_SBX) == 0) 34 SignalException(ReservedInstruction, insn); 35} 36 37 38// MDMX ASE Instructions 39// --------------------- 40// 41// The SB-1 implements the format OB subset of MDMX 42// and has three additions (pavg, pabsdiff, pabsdifc). 43// In addition, there are a couple of partial-decoding 44// issues for the read/write accumulator instructions. 45// 46// This code is structured so that mdmx.igen can be used by 47// selecting the allowed instructions either via model, or by 48// using check_mdmx_fmtsel and check_mdmx_fmtop to cause an 49// exception if the instruction is not allowed. 50 51 52:function:::void:check_mdmx:instruction_word insn 53*sb1: 54{ 55 if (!COP_Usable(1)) 56 SignalExceptionCoProcessorUnusable(1); 57 if ((SR & status_MX) == 0) 58 SignalExceptionMDMX(); 59 check_u64 (SD_, insn); 60} 61 62:function:::int:check_mdmx_fmtsel:instruction_word insn, int fmtsel 63*sb1: 64{ 65 switch (fmtsel & 0x03) 66 { 67 case 0x00: /* ob */ 68 case 0x02: 69 return 1; 70 case 0x01: /* qh */ 71 case 0x03: /* UNPREDICTABLE */ 72 SignalException (ReservedInstruction, insn); 73 return 0; 74 } 75 return 0; 76} 77 78:function:::int:check_mdmx_fmtop:instruction_word insn, int fmtop 79*sb1: 80{ 81 switch (fmtop & 0x01) 82 { 83 case 0x00: /* ob */ 84 return 1; 85 case 0x01: /* qh */ 86 SignalException (ReservedInstruction, insn); 87 return 0; 88 } 89 return 0; 90} 91 92 93011110,10,2.X!0,1.FMTOP,00000,00000,5.VD,111111:MDMX:64::RACH.sb1.fmt 94"rach.?<X>.%s<FMTOP> v<VD>" 95*sb1: 96{ 97 check_mdmx (SD_, instruction_0); 98 check_mdmx_fmtop (SD_, instruction_0, FMTOP); 99 /* No op. */ 100} 101 102 103011110,00,2.X!0,1.FMTOP,00000,00000,5.VD,111111:MDMX:64::RACL.sb1.fmt 104"racl.?<X>.%s<FMTOP> v<VD>" 105*sb1: 106{ 107 check_mdmx (SD_, instruction_0); 108 check_mdmx_fmtop (SD_, instruction_0, FMTOP); 109 /* No op. */ 110} 111 112 113011110,01,2.X!0,1.FMTOP,00000,00000,5.VD,111111:MDMX:64::RACM.sb1.fmt 114"racm.?<X>.%s<FMTOP> v<VD>" 115*sb1: 116{ 117 check_mdmx (SD_, instruction_0); 118 check_mdmx_fmtop (SD_, instruction_0, FMTOP); 119 /* No op. */ 120} 121 122 123011110,2.X1!0!1!2,2.X2,1.FMTOP,00000,00000,5.VD,111111:MDMX:64::RAC.sb1.fmt 124"rac?<X1>.?<X2> v<VD>" 125*sb1: 126{ 127 check_mdmx (SD_, instruction_0); 128 check_mdmx_fmtop (SD_, instruction_0, FMTOP); 129 /* No op. */ 130} 131 132 133011110,10,2.X!0,1.FMTOP,00000,5.VS,00000,111110:MDMX:64::WACH.sb1.fmt 134"wach.?<X>.%s<FMTOP> v<VS>" 135*sb1: 136{ 137 check_mdmx (SD_, instruction_0); 138 check_mdmx_fmtop (SD_, instruction_0, FMTOP); 139 /* No op. */ 140} 141 142 143011110,00,2.X!0,1.FMTOP,5.VT,5.VS,00000,111110:MDMX:64::WACL.sb1.fmt 144"wacl.?<X>.%s<FMTOP> v<VS>,v<VT>" 145*sb1: 146{ 147 check_mdmx (SD_, instruction_0); 148 check_mdmx_fmtop (SD_, instruction_0, FMTOP); 149 /* No op. */ 150} 151 152 153011110,2.X1!0!2,2.X2,1.FMTOP,5.VT,5.VS,00000,111110:MDMX:64::WAC.sb1.fmt 154"wacl?<X1>.?<X2>.%s<FMTOP> v<VS>,v<VT>" 155*sb1: 156{ 157 check_mdmx (SD_, instruction_0); 158 check_mdmx_fmtop (SD_, instruction_0, FMTOP); 159 /* No op. */ 160} 161 162 163011110,5.FMTSEL,5.VT,5.VS,5.VD,001001:MDMX:64::PABSDIFF.fmt 164"pabsdiff.%s<FMTSEL> v<VD>,v<VS>,v<VT>" 165*sb1: 166{ 167 check_mdmx (SD_, instruction_0); 168 check_sbx (SD_, instruction_0); 169 check_mdmx_fmtsel (SD_, instruction_0, FMTSEL); 170 StoreFPR(VD,fmt_mdmx,MX_AbsDiff(ValueFPR(VS,fmt_mdmx),VT,FMTSEL)); 171} 172 173 174011110,5.FMTSEL,5.VT,5.VS,00000,110101:MDMX:64::PABSDIFC.fmt 175"pabsdifc.%s<FMTSEL> v<VS>,v<VT>" 176*sb1: 177{ 178 check_mdmx (SD_, instruction_0); 179 check_sbx (SD_, instruction_0); 180 check_mdmx_fmtsel (SD_, instruction_0, FMTSEL); 181 MX_AbsDiffC(ValueFPR(VS,fmt_mdmx),VT,FMTSEL); 182} 183 184 185011110,5.FMTSEL,5.VT,5.VS,5.VD,001000:MDMX:64::PAVG.fmt 186"pavg.%s<FMTSEL> v<VD>,v<VS>,v<VT>" 187*sb1: 188{ 189 check_mdmx (SD_, instruction_0); 190 check_sbx (SD_, instruction_0); 191 check_mdmx_fmtsel (SD_, instruction_0, FMTSEL); 192 StoreFPR(VD,fmt_mdmx,MX_Avg(ValueFPR(VS,fmt_mdmx),VT,FMTSEL)); 193} 194 195 196// Paired-Single Extension Instructions 197// ------------------------------------ 198// 199// The SB-1 implements several .PS format instructions that are 200// extensions to the MIPS64 architecture. 201 202010001,10,3.FMT=6,5.FT,5.FS,5.FD,000011:COP1:32,f::DIV.PS 203"div.%s<FMT> f<FD>, f<FS>, f<FT>" 204*sb1: 205{ 206 int fmt = FMT; 207 check_fpu (SD_); 208 check_sbx (SD_, instruction_0); 209 StoreFPR (FD, fmt, Divide (ValueFPR (FS, fmt), ValueFPR (FT, fmt), fmt)); 210} 211 212 213010001,10,3.FMT=6,00000,5.FS,5.FD,010101:COP1:32,f::RECIP.PS 214"recip.%s<FMT> f<FD>, f<FS>" 215*sb1: 216{ 217 int fmt = FMT; 218 check_fpu (SD_); 219 check_sbx (SD_, instruction_0); 220 StoreFPR (FD, fmt, Recip (ValueFPR (FS, fmt), fmt)); 221} 222 223 224010001,10,3.FMT=6,00000,5.FS,5.FD,010110:COP1:32,f::RSQRT.PS 225"rsqrt.%s<FMT> f<FD>, f<FS>" 226*sb1: 227{ 228 int fmt = FMT; 229 check_fpu (SD_); 230 check_sbx (SD_, instruction_0); 231 StoreFPR (FD, fmt, RSquareRoot (ValueFPR (FS, fmt), fmt)); 232} 233 234 235010001,10,3.FMT=6,00000,5.FS,5.FD,000100:COP1:32,f::SQRT.PS 236"sqrt.%s<FMT> f<FD>, f<FS>" 237*sb1: 238{ 239 int fmt = FMT; 240 check_fpu (SD_); 241 check_sbx (SD_, instruction_0); 242 StoreFPR (FD, fmt, (SquareRoot (ValueFPR (FS, fmt), fmt))); 243} 244