fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
1/*****************************************************************************
2 * pce *
3 *****************************************************************************/
4
5/*****************************************************************************
6 * File name: src/cpu/arm/internal.h *
7 * Created: 2004-11-03 by Hampa Hug <hampa@hampa.ch> *
8 * Copyright: (C) 2004-2009 Hampa Hug <hampa@hampa.ch> *
9 * Copyright: (C) 2004-2006 Lukas Ruf <ruf@lpr.ch> *
10 *****************************************************************************/
11
12/*****************************************************************************
13 * This program is free software. You can redistribute it and / or modify it *
14 * under the terms of the GNU General Public License version 2 as published *
15 * by the Free Software Foundation. *
16 * *
17 * This program is distributed in the hope that it will be useful, but *
18 * WITHOUT ANY WARRANTY, without even the implied warranty of *
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General *
20 * Public License for more details. *
21 *****************************************************************************/
22
23/*****************************************************************************
24 * This software was developed at the Computer Engineering and Networks *
25 * Laboratory (TIK), Swiss Federal Institute of Technology (ETH) Zurich. *
26 *****************************************************************************/
27
28
29#ifndef ARM_INTERNAL_H
30#define ARM_INTERNAL_H
31
32
33#include <stdlib.h>
34#include <stdio.h>
35
36
37/*****************************************************************************
38 * MMU
39 *****************************************************************************/
40
41int arm_ifetch (arm_t *c, uint32_t addr, uint32_t *val);
42
43int arm_dload8 (arm_t *c, uint32_t addr, uint8_t *val);
44int arm_dload16 (arm_t *c, uint32_t addr, uint16_t *val);
45int arm_dload32 (arm_t *c, uint32_t addr, uint32_t *val);
46
47int arm_dstore8 (arm_t *c, uint32_t addr, uint8_t val);
48int arm_dstore16 (arm_t *c, uint32_t addr, uint16_t val);
49int arm_dstore32 (arm_t *c, uint32_t addr, uint32_t val);
50
51int arm_dload8_t (arm_t *c, uint32_t addr, uint8_t *val);
52int arm_dload16_t (arm_t *c, uint32_t addr, uint16_t *val);
53int arm_dload32_t (arm_t *c, uint32_t addr, uint32_t *val);
54
55int arm_dstore8_t (arm_t *c, uint32_t addr, uint8_t val);
56int arm_dstore16_t (arm_t *c, uint32_t addr, uint16_t val);
57int arm_dstore32_t (arm_t *c, uint32_t addr, uint32_t val);
58
59
60/*****************************************************************************
61 * arm
62 *****************************************************************************/
63
64#define arm_get_bit(v, i) (((v) >> (i)) & 1)
65#define arm_get_bits(v, i, n) (((v) >> (i)) & ((1UL << (n)) - 1))
66
67#define arm_exts(x, n) ( \
68 ((x) & (1UL << ((n) - 1))) ? \
69 (((x) | ~((1UL << (n)) - 1)) & 0xffffffffUL) : \
70 ((x) & ((1UL << (n)) - 1)) \
71 )
72
73#define arm_extu(x, n) ((x) & ((1UL << (n)) - 1))
74
75#define arm_ir_cond(ir) (((ir) >> 28) & 0x0f)
76#define arm_ir_rn(ir) (((ir) >> 16) & 0x0f)
77#define arm_ir_rd(ir) (((ir) >> 12) & 0x0f)
78#define arm_ir_rs(ir) (((ir) >> 8) & 0x0f)
79#define arm_ir_rm(ir) ((ir) & 0x0f)
80#define arm_ir_s(ir) (((ir) >> 20) & 0x01)
81#define arm_ir_i(ir) (((ir) >> 25) & 0x01)
82
83#define arm_rd_is_pc(ir) ((((ir) >> 12) & 0x0f) == 15)
84
85#define arm_is_shext(ir) (((ir) & 0x02000090UL) == 0x00000090UL)
86#define arm_get_shext(ir) (((ir) >> 4) & 0x0f)
87
88static inline
89uint32_t arm_get_reg_pc (arm_t *c, unsigned reg, uint32_t pc)
90{
91 if (reg == 15) {
92 return ((arm_get_gpr (c, 15) + pc) & 0xffffffff);
93 }
94
95 return (arm_get_gpr (c, reg));
96}
97
98#define arm_get_rn(c, ir) (arm_get_reg_pc ((c), arm_ir_rn(ir), 8))
99#define arm_get_rd(c, ir) (arm_get_reg_pc ((c), arm_ir_rd(ir), 8))
100#define arm_get_rs(c, ir) (arm_get_reg_pc ((c), arm_ir_rs(ir), 8))
101#define arm_get_rm(c, ir) (arm_get_reg_pc ((c), arm_ir_rm(ir), 8))
102
103#define arm_set_rn(c, ir, v) do { arm_set_gpr ((c), arm_ir_rn(ir), (v)); } while (0)
104#define arm_set_rd(c, ir, v) do { arm_set_gpr ((c), arm_ir_rd(ir), (v)); } while (0)
105
106#define arm_set_clk(c, dpc, clk) do { \
107 (c)->reg[15] += (dpc); \
108 (c)->delay += (clk); \
109} while (0)
110
111
112#define arm_check_cond_al(ir) (((ir) & 0xf0000000UL) == 0xe0000000UL)
113
114#define arm_is_privileged(c) ((c)->privileged)
115
116
117static inline
118uint32_t arm_ror32 (uint32_t v, unsigned n)
119{
120 n &= 31;
121
122 if (n > 0) {
123 v = ((v >> n) | (v << (32 - n))) & 0xffffffff;
124 }
125
126 return (v);
127}
128
129static inline
130uint32_t arm_asr32 (uint32_t v, unsigned n)
131{
132 n &= 31;
133
134 if (n > 0) {
135 if (v & 0x80000000) {
136 v = ((v >> n) | (0xffffffff << (32 - n))) & 0xffffffff;
137 }
138 else {
139 v = v >> n;
140 }
141 }
142
143 return (v);
144}
145
146static inline
147void arm_tbuf_flush (arm_t *c)
148{
149 arm_copr15_t *mmu = arm_get_mmu (c);
150
151 mmu->tbuf_exec.valid = 0;
152 mmu->tbuf_read.valid = 0;
153 mmu->tbuf_write.valid = 0;
154}
155
156
157int arm_write_cpsr (arm_t *c, uint32_t val, int prvchk);
158
159int arm_check_cond (arm_t *c, unsigned cond);
160
161void arm_set_opcodes (arm_t *c);
162
163
164#endif