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