/[gxemul]/upstream/0.3.4/src/cpu_mips16.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /upstream/0.3.4/src/cpu_mips16.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 11 - (show annotations)
Mon Oct 8 16:18:31 2007 UTC (16 years, 7 months ago) by dpavlin
File MIME type: text/plain
File size: 5030 byte(s)
0.3.4
1 /*
2 * Copyright (C) 2003-2005 Anders Gavare. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. The name of the author may not be used to endorse or promote products
13 * derived from this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 *
28 * $Id: cpu_mips16.c,v 1.2 2005/02/21 07:18:11 debug Exp $
29 *
30 * MIPS16 encoding support, 16-bit to 32-bit instruction translation.
31 *
32 * Included from cpu_mips.c.
33 */
34
35 #ifndef ENABLE_MIPS16
36
37 /* Dummy functions if MIPS16 support is not to be included: */
38 int mips16_to_32(struct cpu *cpu, unsigned char *instr16,
39 unsigned char *instr)
40 {
41 fatal("mips16_to_32(): internal error! this function shouldn't "
42 "be called if ENABLE_MIPS16 isn't defined!\n");
43 return 0;
44 }
45
46 #else
47
48
49 /* MIPS16 register numbers: */
50 static int mips16_reg8_to_reg32[8] = {
51 MIPS_GPR_S0, MIPS_GPR_S1, MIPS_GPR_V0, MIPS_GPR_V1,
52 MIPS_GPR_A0, MIPS_GPR_A1, MIPS_GPR_A2, MIPS_GPR_A3
53 };
54
55 static int mips16_sp = MIPS_GPR_SP;
56 /* static int mips16_t = MIPS_GPR_T8; */
57
58
59 /*
60 * mips16_to_32():
61 *
62 * Translate a 16-bit MIPS16 instruction word into a normal 32-bit instruction
63 * word. instr16[1..0] ==> instr[3..0].
64 *
65 * Returns 1 if there is a resulting 32-bit instruction, 0 if this is an
66 * "extend".
67 */
68 int mips16_to_32(struct cpu *cpu, unsigned char *instr16, unsigned char *instr)
69 {
70 int rs, rd, imm, wlen;
71 int x = (instr16[1] << 8) + instr16[0];
72 int y = 0x3e << 26; /* This should be something 'illegal',
73 so that execution stops */
74
75 /* Translate 16-bit x into 32-bit y: */
76
77 /* extend: */
78 if ((x & 0xf800) == 0xf000) {
79 /* TODO: what happens if an extend is interrupted? */
80 cpu->cd.mips.mips16_extend = x; /* save x until later */
81 return 0;
82 }
83
84 /* nop: */
85 if ((x & 0xffff) == 0x6500) {
86 y = 0x00000000; /* nop */
87 goto mips16_ret;
88 }
89
90 /* move y,X: 0x67 + 3 bits rd + 5 bits rs */
91 if ((x & 0xff00) == 0x6700) {
92 rd = (x >> 5) & 0x07;
93 rs = (x >> 0) & 0x1f;
94 /* addiu mips16_reg8_to_reg32[rd], reg32[rs], 0 */
95 y = (HI6_ADDIU << 26) + (rs << 21) +
96 (mips16_reg8_to_reg32[rd] << 16);
97 goto mips16_ret;
98 }
99
100 /* ld y,D(x) { ld "y,D(x)", 0x3800, 0xf800, WR_y|RD_x, I3 } */
101 if ((x & 0xf800) == 0x3800) {
102 wlen = 8; /* for ld */
103 rd = (x >> 5) & 0x07;
104 rs = (x >> 8) & 0x07;
105 if (cpu->cd.mips.mips16_extend)
106 imm = (cpu->cd.mips.mips16_extend & 0x7ff) +
107 ((x & 0x1f) << 11);
108 else {
109 imm = (x & 0x1f) * wlen;
110 if (imm >= 0x10)
111 imm |= 0xffe0; /* sign-extend */
112 }
113
114 y = (HI6_LD << 26) + (mips16_reg8_to_reg32[rd] << 16) +
115 (rs << 21) + imm;
116 goto mips16_ret;
117 }
118
119 /* sd y,D(S) 0xf900, 0xff00, RD_y|RD_PC, I3 */
120 if ((x & 0xff00) == 0xf900) {
121 wlen = 8; /* for sd */
122 rd = (x >> 5) & 0x07;
123 rs = (x >> 8) & 0x07;
124
125 /* TODO */
126
127 if (cpu->cd.mips.mips16_extend) {
128 imm = (cpu->cd.mips.mips16_extend & 0x7ff) +
129 ((x & 0x1f) << 11);
130 } else {
131 imm = (x & 0x1f) * wlen;
132 if (imm >= 0x10)
133 imm |= 0xffe0; /* sign-extend */
134 }
135
136 y = (HI6_SD << 26) + (mips16_reg8_to_reg32[rd] << 16) +
137 (rs << 21) + imm;
138 goto mips16_ret;
139 }
140
141 /* daddiu "S,K", 0xfb00, 0xff00, WR_SP|RD_SP, I3 */
142 if ((x & 0xff00) == 0xfb00) {
143
144 /* TODO: this is wrong */
145
146 if (cpu->cd.mips.mips16_extend) {
147 imm = ((cpu->cd.mips.mips16_extend & 0x7ff) << 5) +
148 (x & 0xff);
149 } else {
150 imm = (x & 0xff) << 3;
151 if (imm & (1 << 10))
152 imm |= 0xf800; /* sign-extend */
153 }
154
155 y = (HI6_DADDIU << 26) + (mips16_sp << 21) + (mips16_sp << 16)
156 + (imm & 0xffff);
157 goto mips16_ret;
158 }
159
160 /* fatal("WARNING: unimplemented MIPS16 instruction 0x%04x\n", x); */
161
162 mips16_ret:
163 instr[3] = y >> 24; instr[2] = y >> 16;
164 instr[1] = y >> 8; instr[0] = y;
165 return 1;
166 }
167
168
169 #endif /* ENABLE_MIPS16 */

  ViewVC Help
Powered by ViewVC 1.1.26