Revision e96e2044 target-sh4/helper.c

b/target-sh4/helper.c
27 27

  
28 28
#include "cpu.h"
29 29
#include "exec-all.h"
30
#include "hw/sh_intc.h"
30 31

  
31 32
#if defined(CONFIG_USER_ONLY)
32 33

  
......
74 75

  
75 76
void do_interrupt(CPUState * env)
76 77
{
78
    int do_irq = env->interrupt_request & CPU_INTERRUPT_HARD;
79
    int do_exp, irq_vector = env->exception_index;
80

  
81
    /* prioritize exceptions over interrupts */
82

  
83
    do_exp = env->exception_index != -1;
84
    do_irq = do_irq && (env->exception_index == -1);
85

  
86
    if (env->sr & SR_BL) {
87
        if (do_exp && env->exception_index != 0x1e0) {
88
            env->exception_index = 0x000; /* masked exception -> reset */
89
        }
90
        if (do_irq) {
91
            return; /* masked */
92
        }
93
    }
94

  
95
    if (do_irq) {
96
        irq_vector = sh_intc_get_pending_vector(env->intc_handle,
97
						(env->sr >> 4) & 0xf);
98
        if (irq_vector == -1) {
99
            return; /* masked */
100
	}
101
    }
102

  
77 103
    if (loglevel & CPU_LOG_INT) {
78 104
	const char *expname;
79 105
	switch (env->exception_index) {
......
117 143
	    expname = "trapa";
118 144
	    break;
119 145
	default:
120
	    expname = "???";
121
	    break;
146
            expname = do_irq ? "interrupt" : "???";
147
            break;
122 148
	}
123 149
	fprintf(logfile, "exception 0x%03x [%s] raised\n",
124
		env->exception_index, expname);
150
		irq_vector, expname);
125 151
	cpu_dump_state(env, logfile, fprintf, 0);
126 152
    }
127 153

  
128 154
    env->ssr = env->sr;
129
    env->spc = env->spc;
155
    env->spc = env->pc;
130 156
    env->sgr = env->gregs[15];
131 157
    env->sr |= SR_BL | SR_MD | SR_RB;
132 158

  
133
    env->expevt = env->exception_index & 0x7ff;
134
    switch (env->exception_index) {
135
    case 0x040:
136
    case 0x060:
137
    case 0x080:
138
	env->pc = env->vbr + 0x400;
139
	break;
140
    case 0x140:
141
	env->pc = 0xa0000000;
142
	break;
143
    default:
144
	env->pc = env->vbr + 0x100;
145
	break;
159
    if (do_exp) {
160
        env->expevt = env->exception_index;
161
        switch (env->exception_index) {
162
        case 0x000:
163
        case 0x020:
164
        case 0x140:
165
            env->sr &= ~SR_FD;
166
            env->sr |= 0xf << 4; /* IMASK */
167
            env->pc = 0xa0000000;
168
            break;
169
        case 0x040:
170
        case 0x060:
171
            env->pc = env->vbr + 0x400;
172
            break;
173
        case 0x160:
174
            env->spc += 2; /* special case for TRAPA */
175
            /* fall through */
176
        default:
177
            env->pc = env->vbr + 0x100;
178
            break;
179
        }
180
        return;
181
    }
182

  
183
    if (do_irq) {
184
        env->intevt = irq_vector;
185
        env->pc = env->vbr + 0x600;
186
        return;
146 187
    }
147 188
}
148 189

  

Also available in: Unified diff