/[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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 11 - (hide annotations)
Mon Oct 8 16:18:31 2007 UTC (16 years, 8 months ago) by dpavlin
File MIME type: text/plain
File size: 5030 byte(s)
0.3.4
1 dpavlin 2 /*
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