Revision 527d9979

b/target-unicore32/helper.c
14 14
#include "helper.h"
15 15
#include "host-utils.h"
16 16

  
17
#undef DEBUG_UC32
18

  
19
#ifdef DEBUG_UC32
20
#define DPRINTF(fmt, ...) printf("%s: " fmt , __func__, ## __VA_ARGS__)
21
#else
22
#define DPRINTF(fmt, ...) do {} while (0)
23
#endif
24

  
17 25
CPUUniCore32State *uc32_cpu_init(const char *cpu_model)
18 26
{
19 27
    UniCore32CPU *cpu;
......
45 53
    return clz32(x);
46 54
}
47 55

  
56
#ifndef CONFIG_USER_ONLY
57
void helper_cp0_set(CPUUniCore32State *env, uint32_t val, uint32_t creg,
58
        uint32_t cop)
59
{
60
    /*
61
     * movc pp.nn, rn, #imm9
62
     *      rn: UCOP_REG_D
63
     *      nn: UCOP_REG_N
64
     *          1: sys control reg.
65
     *          2: page table base reg.
66
     *          3: data fault status reg.
67
     *          4: insn fault status reg.
68
     *          5: cache op. reg.
69
     *          6: tlb op. reg.
70
     *      imm9: split UCOP_IMM10 with bit5 is 0
71
     */
72
    switch (creg) {
73
    case 1:
74
        if (cop != 0) {
75
            goto unrecognized;
76
        }
77
        env->cp0.c1_sys = val;
78
        break;
79
    case 2:
80
        if (cop != 0) {
81
            goto unrecognized;
82
        }
83
        env->cp0.c2_base = val;
84
        break;
85
    case 3:
86
        if (cop != 0) {
87
            goto unrecognized;
88
        }
89
        env->cp0.c3_faultstatus = val;
90
        break;
91
    case 4:
92
        if (cop != 0) {
93
            goto unrecognized;
94
        }
95
        env->cp0.c4_faultaddr = val;
96
        break;
97
    case 5:
98
        switch (cop) {
99
        case 28:
100
            DPRINTF("Invalidate Entire I&D cache\n");
101
            return;
102
        case 20:
103
            DPRINTF("Invalidate Entire Icache\n");
104
            return;
105
        case 12:
106
            DPRINTF("Invalidate Entire Dcache\n");
107
            return;
108
        case 10:
109
            DPRINTF("Clean Entire Dcache\n");
110
            return;
111
        case 14:
112
            DPRINTF("Flush Entire Dcache\n");
113
            return;
114
        case 13:
115
            DPRINTF("Invalidate Dcache line\n");
116
            return;
117
        case 11:
118
            DPRINTF("Clean Dcache line\n");
119
            return;
120
        case 15:
121
            DPRINTF("Flush Dcache line\n");
122
            return;
123
        }
124
        break;
125
    case 6:
126
        if ((cop <= 6) && (cop >= 2)) {
127
            /* invalid all tlb */
128
            tlb_flush(env, 1);
129
            return;
130
        }
131
        break;
132
    default:
133
        goto unrecognized;
134
    }
135
    return;
136
unrecognized:
137
    DPRINTF("Wrong register (%d) or wrong operation (%d) in cp0_set!\n",
138
            creg, cop);
139
}
140

  
141
uint32_t helper_cp0_get(CPUUniCore32State *env, uint32_t creg, uint32_t cop)
142
{
143
    /*
144
     * movc rd, pp.nn, #imm9
145
     *      rd: UCOP_REG_D
146
     *      nn: UCOP_REG_N
147
     *          0: cpuid and cachetype
148
     *          1: sys control reg.
149
     *          2: page table base reg.
150
     *          3: data fault status reg.
151
     *          4: insn fault status reg.
152
     *      imm9: split UCOP_IMM10 with bit5 is 0
153
     */
154
    switch (creg) {
155
    case 0:
156
        switch (cop) {
157
        case 0:
158
            return env->cp0.c0_cpuid;
159
        case 1:
160
            return env->cp0.c0_cachetype;
161
        }
162
        break;
163
    case 1:
164
        if (cop == 0) {
165
            return env->cp0.c1_sys;
166
        }
167
        break;
168
    case 2:
169
        if (cop == 0) {
170
            return env->cp0.c2_base;
171
        }
172
        break;
173
    case 3:
174
        if (cop == 0) {
175
            return env->cp0.c3_faultstatus;
176
        }
177
        break;
178
    case 4:
179
        if (cop == 0) {
180
            return env->cp0.c4_faultaddr;
181
        }
182
        break;
183
    }
184
    DPRINTF("Wrong register (%d) or wrong operation (%d) in cp0_set!\n",
185
            creg, cop);
186
    return 0;
187
}
188

  
189
void helper_cp1_putc(target_ulong x)
190
{
191
    /* TODO: curses display should be added here for screen output. */
192
    DPRINTF("%c", x);
193
}
194
#endif
195

  
48 196
#ifdef CONFIG_USER_ONLY
49 197
void switch_mode(CPUUniCore32State *env, int mode)
50 198
{
......
66 214
}
67 215
#endif
68 216

  
69
/* These should probably raise undefined insn exceptions.  */
70
void HELPER(set_cp)(CPUUniCore32State *env, uint32_t insn, uint32_t val)
71
{
72
    int op1 = (insn >> 8) & 0xf;
73
    cpu_abort(env, "cp%i insn %08x\n", op1, insn);
74
    return;
75
}
76

  
77
uint32_t HELPER(get_cp)(CPUUniCore32State *env, uint32_t insn)
78
{
79
    int op1 = (insn >> 8) & 0xf;
80
    cpu_abort(env, "cp%i insn %08x\n", op1, insn);
81
    return 0;
82
}
83

  
84
void HELPER(set_cp0)(CPUUniCore32State *env, uint32_t insn, uint32_t val)
85
{
86
    cpu_abort(env, "cp0 insn %08x\n", insn);
87
}
88

  
89
uint32_t HELPER(get_cp0)(CPUUniCore32State *env, uint32_t insn)
90
{
91
    cpu_abort(env, "cp0 insn %08x\n", insn);
92
    return 0;
93
}
94

  
95
void HELPER(set_r29_banked)(CPUUniCore32State *env, uint32_t mode, uint32_t val)
96
{
97
    cpu_abort(env, "banked r29 write\n");
98
}
99

  
100
uint32_t HELPER(get_r29_banked)(CPUUniCore32State *env, uint32_t mode)
101
{
102
    cpu_abort(env, "banked r29 read\n");
103
    return 0;
104
}
105

  
106 217
/* UniCore-F64 support.  We follow the convention used for F64 instrunctions:
107 218
   Single precition routines have a "s" suffix, double precision a
108 219
   "d" suffix.  */
b/target-unicore32/helper.h
1 1
/*
2
 * Copyright (C) 2010-2011 GUAN Xue-tao
2
 * Copyright (C) 2010-2012 Guan Xuetao
3 3
 *
4 4
 * This program is free software; you can redistribute it and/or modify
5 5
 * it under the terms of the GNU General Public License version 2 as
......
8 8
 */
9 9
#include "def-helper.h"
10 10

  
11
#ifndef CONFIG_USER_ONLY
12
DEF_HELPER_4(cp0_set, void, env, i32, i32, i32)
13
DEF_HELPER_3(cp0_get, i32, env, i32, i32)
14
DEF_HELPER_1(cp1_putc, void, i32)
15
#endif
16

  
11 17
DEF_HELPER_1(clz, i32, i32)
12 18
DEF_HELPER_1(clo, i32, i32)
13 19

  
......
16 22
DEF_HELPER_2(asr_write, void, i32, i32)
17 23
DEF_HELPER_0(asr_read, i32)
18 24

  
19
DEF_HELPER_3(set_cp0, void, env, i32, i32)
20
DEF_HELPER_2(get_cp0, i32, env, i32)
21

  
22
DEF_HELPER_3(set_cp, void, env, i32, i32)
23
DEF_HELPER_2(get_cp, i32, env, i32)
24

  
25 25
DEF_HELPER_1(get_user_reg, i32, i32)
26 26
DEF_HELPER_2(set_user_reg, void, i32, i32)
27 27

  
......
38 38
DEF_HELPER_2(sar_cc, i32, i32, i32)
39 39
DEF_HELPER_2(ror_cc, i32, i32, i32)
40 40

  
41
DEF_HELPER_2(get_r29_banked, i32, env, i32)
42
DEF_HELPER_3(set_r29_banked, void, env, i32, i32)
43

  
44 41
DEF_HELPER_1(ucf64_get_fpscr, i32, env)
45 42
DEF_HELPER_2(ucf64_set_fpscr, void, env, i32)
46 43

  
b/target-unicore32/translate.c
1 1
/*
2 2
 *  UniCore32 translation
3 3
 *
4
 * Copyright (C) 2010-2011 GUAN Xue-tao
4
 * Copyright (C) 2010-2012 Guan Xuetao
5 5
 *
6 6
 * This program is free software; you can redistribute it and/or modify
7 7
 * it under the terms of the GNU General Public License version 2 as
......
176 176
                        "Illegal UniCore32 instruction %x at line %d!", \
177 177
                        insn, __LINE__)
178 178

  
179
#ifndef CONFIG_USER_ONLY
180
static void disas_cp0_insn(CPUUniCore32State *env, DisasContext *s,
181
        uint32_t insn)
182
{
183
    TCGv tmp, tmp2, tmp3;
184
    if ((insn & 0xfe000000) == 0xe0000000) {
185
        tmp2 = new_tmp();
186
        tmp3 = new_tmp();
187
        tcg_gen_movi_i32(tmp2, UCOP_REG_N);
188
        tcg_gen_movi_i32(tmp3, UCOP_IMM10);
189
        if (UCOP_SET_L) {
190
            tmp = new_tmp();
191
            gen_helper_cp0_get(tmp, cpu_env, tmp2, tmp3);
192
            store_reg(s, UCOP_REG_D, tmp);
193
        } else {
194
            tmp = load_reg(s, UCOP_REG_D);
195
            gen_helper_cp0_set(cpu_env, tmp, tmp2, tmp3);
196
            dead_tmp(tmp);
197
        }
198
        dead_tmp(tmp2);
199
        dead_tmp(tmp3);
200
        return;
201
    }
202
    ILLEGAL;
203
}
204

  
205
static void disas_ocd_insn(CPUUniCore32State *env, DisasContext *s,
206
        uint32_t insn)
207
{
208
    TCGv tmp;
209

  
210
    if ((insn & 0xff003fff) == 0xe1000400) {
211
        /*
212
         * movc rd, pp.nn, #imm9
213
         *      rd: UCOP_REG_D
214
         *      nn: UCOP_REG_N (must be 0)
215
         *      imm9: 0
216
         */
217
        if (UCOP_REG_N == 0) {
218
            tmp = new_tmp();
219
            tcg_gen_movi_i32(tmp, 0);
220
            store_reg(s, UCOP_REG_D, tmp);
221
            return;
222
        } else {
223
            ILLEGAL;
224
        }
225
    }
226
    if ((insn & 0xff003fff) == 0xe0000401) {
227
        /*
228
         * movc pp.nn, rn, #imm9
229
         *      rn: UCOP_REG_D
230
         *      nn: UCOP_REG_N (must be 1)
231
         *      imm9: 1
232
         */
233
        if (UCOP_REG_N == 1) {
234
            tmp = load_reg(s, UCOP_REG_D);
235
            gen_helper_cp1_putc(tmp);
236
            dead_tmp(tmp);
237
            return;
238
        } else {
239
            ILLEGAL;
240
        }
241
    }
242
    ILLEGAL;
243
}
244
#endif
245

  
179 246
static inline void gen_set_asr(TCGv var, uint32_t mask)
180 247
{
181 248
    TCGv tmp_mask = tcg_const_i32(mask);
......
1124 1191
    s->is_jmp = DISAS_UPDATE;
1125 1192
}
1126 1193

  
1127
static void disas_coproc_insn(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
1194
static void disas_coproc_insn(CPUUniCore32State *env, DisasContext *s,
1195
        uint32_t insn)
1128 1196
{
1129 1197
    switch (UCOP_CPNUM) {
1198
#ifndef CONFIG_USER_ONLY
1199
    case 0:
1200
        disas_cp0_insn(env, s, insn);
1201
        break;
1202
    case 1:
1203
        disas_ocd_insn(env, s, insn);
1204
        break;
1205
#endif
1130 1206
    case 2:
1131 1207
        disas_ucf64_insn(env, s, insn);
1132 1208
        break;

Also available in: Unified diff