198b9484cSchristos /* armvirt.c -- ARMulator virtual memory interace: ARM6 Instruction Emulator.
298b9484cSchristos Copyright (C) 1994 Advanced RISC Machines Ltd.
398b9484cSchristos
498b9484cSchristos This program is free software; you can redistribute it and/or modify
598b9484cSchristos it under the terms of the GNU General Public License as published by
6a2e2270fSchristos the Free Software Foundation; either version 3 of the License, or
798b9484cSchristos (at your option) any later version.
898b9484cSchristos
998b9484cSchristos This program is distributed in the hope that it will be useful,
1098b9484cSchristos but WITHOUT ANY WARRANTY; without even the implied warranty of
1198b9484cSchristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1298b9484cSchristos GNU General Public License for more details.
1398b9484cSchristos
1498b9484cSchristos You should have received a copy of the GNU General Public License
15a2e2270fSchristos along with this program; if not, see <http://www.gnu.org/licenses/>. */
1698b9484cSchristos
1798b9484cSchristos /* This file contains a complete ARMulator memory model, modelling a
1898b9484cSchristos "virtual memory" system. A much simpler model can be found in armfast.c,
1998b9484cSchristos and that model goes faster too, but has a fixed amount of memory. This
2098b9484cSchristos model's memory has 64K pages, allocated on demand from a 64K entry page
2198b9484cSchristos table. The routines PutWord and GetWord implement this. Pages are never
2298b9484cSchristos freed as they might be needed again. A single area of memory may be
2398b9484cSchristos defined to generate aborts. */
2498b9484cSchristos
25*4b169a6bSchristos /* This must come before any other includes. */
26*4b169a6bSchristos #include "defs.h"
27*4b169a6bSchristos
2898b9484cSchristos #include "armos.h"
2998b9484cSchristos #include "armdefs.h"
3098b9484cSchristos #include "ansidecl.h"
3198b9484cSchristos
3298b9484cSchristos #ifdef VALIDATE /* for running the validate suite */
3398b9484cSchristos #define TUBE 48 * 1024 * 1024 /* write a char on the screen */
3498b9484cSchristos #define ABORTS 1
3598b9484cSchristos #endif
3698b9484cSchristos
3798b9484cSchristos /* #define ABORTS */
3898b9484cSchristos
3998b9484cSchristos #ifdef ABORTS /* the memory system will abort */
4098b9484cSchristos /* For the old test suite Abort between 32 Kbytes and 32 Mbytes
4198b9484cSchristos For the new test suite Abort between 8 Mbytes and 26 Mbytes */
4298b9484cSchristos /* #define LOWABORT 32 * 1024
4398b9484cSchristos #define HIGHABORT 32 * 1024 * 1024 */
4498b9484cSchristos #define LOWABORT 8 * 1024 * 1024
4598b9484cSchristos #define HIGHABORT 26 * 1024 * 1024
4698b9484cSchristos
4798b9484cSchristos #endif
4898b9484cSchristos
49*4b169a6bSchristos #undef PAGESIZE /* Cleanup system headers. */
5098b9484cSchristos #define NUMPAGES 64 * 1024
5198b9484cSchristos #define PAGESIZE 64 * 1024
5298b9484cSchristos #define PAGEBITS 16
5398b9484cSchristos #define OFFSETBITS 0xffff
5498b9484cSchristos
5598b9484cSchristos int SWI_vector_installed = FALSE;
5698b9484cSchristos
5798b9484cSchristos /***************************************************************************\
5898b9484cSchristos * Get a Word from Virtual Memory, maybe allocating the page *
5998b9484cSchristos \***************************************************************************/
6098b9484cSchristos
6198b9484cSchristos static ARMword
GetWord(ARMul_State * state,ARMword address,int check)6298b9484cSchristos GetWord (ARMul_State * state, ARMword address, int check)
6398b9484cSchristos {
6498b9484cSchristos ARMword page;
6598b9484cSchristos ARMword offset;
6698b9484cSchristos ARMword **pagetable;
6798b9484cSchristos ARMword *pageptr;
6898b9484cSchristos
6998b9484cSchristos if (check && state->is_XScale)
7098b9484cSchristos XScale_check_memacc (state, &address, 0);
7198b9484cSchristos
7298b9484cSchristos page = address >> PAGEBITS;
7398b9484cSchristos offset = (address & OFFSETBITS) >> 2;
7498b9484cSchristos pagetable = (ARMword **) state->MemDataPtr;
7598b9484cSchristos pageptr = *(pagetable + page);
7698b9484cSchristos
7798b9484cSchristos if (pageptr == NULL)
7898b9484cSchristos {
7998b9484cSchristos pageptr = (ARMword *) malloc (PAGESIZE);
8098b9484cSchristos
8198b9484cSchristos if (pageptr == NULL)
8298b9484cSchristos {
8398b9484cSchristos perror ("ARMulator can't allocate VM page");
8498b9484cSchristos exit (12);
8598b9484cSchristos }
8698b9484cSchristos
8798b9484cSchristos *(pagetable + page) = pageptr;
8898b9484cSchristos }
8998b9484cSchristos
9098b9484cSchristos return *(pageptr + offset);
9198b9484cSchristos }
9298b9484cSchristos
9398b9484cSchristos /***************************************************************************\
9498b9484cSchristos * Put a Word into Virtual Memory, maybe allocating the page *
9598b9484cSchristos \***************************************************************************/
9698b9484cSchristos
9798b9484cSchristos static void
PutWord(ARMul_State * state,ARMword address,ARMword data,int check)9898b9484cSchristos PutWord (ARMul_State * state, ARMword address, ARMword data, int check)
9998b9484cSchristos {
10098b9484cSchristos ARMword page;
10198b9484cSchristos ARMword offset;
10298b9484cSchristos ARMword **pagetable;
10398b9484cSchristos ARMword *pageptr;
10498b9484cSchristos
10598b9484cSchristos if (check && state->is_XScale)
10698b9484cSchristos XScale_check_memacc (state, &address, 1);
10798b9484cSchristos
10898b9484cSchristos page = address >> PAGEBITS;
10998b9484cSchristos offset = (address & OFFSETBITS) >> 2;
11098b9484cSchristos pagetable = (ARMword **) state->MemDataPtr;
11198b9484cSchristos pageptr = *(pagetable + page);
11298b9484cSchristos
11398b9484cSchristos if (pageptr == NULL)
11498b9484cSchristos {
11598b9484cSchristos pageptr = (ARMword *) malloc (PAGESIZE);
11698b9484cSchristos if (pageptr == NULL)
11798b9484cSchristos {
11898b9484cSchristos perror ("ARMulator can't allocate VM page");
11998b9484cSchristos exit (13);
12098b9484cSchristos }
12198b9484cSchristos
12298b9484cSchristos *(pagetable + page) = pageptr;
12398b9484cSchristos }
12498b9484cSchristos
12598b9484cSchristos if (address == 0x8)
12698b9484cSchristos SWI_vector_installed = TRUE;
12798b9484cSchristos
12898b9484cSchristos *(pageptr + offset) = data;
12998b9484cSchristos }
13098b9484cSchristos
13198b9484cSchristos /***************************************************************************\
13298b9484cSchristos * Initialise the memory interface *
13398b9484cSchristos \***************************************************************************/
13498b9484cSchristos
13598b9484cSchristos unsigned
ARMul_MemoryInit(ARMul_State * state,unsigned long initmemsize)13698b9484cSchristos ARMul_MemoryInit (ARMul_State * state, unsigned long initmemsize)
13798b9484cSchristos {
13898b9484cSchristos ARMword **pagetable;
13998b9484cSchristos unsigned page;
14098b9484cSchristos
14198b9484cSchristos if (initmemsize)
14298b9484cSchristos state->MemSize = initmemsize;
14398b9484cSchristos
14498b9484cSchristos pagetable = (ARMword **) malloc (sizeof (ARMword *) * NUMPAGES);
14598b9484cSchristos
14698b9484cSchristos if (pagetable == NULL)
14798b9484cSchristos return FALSE;
14898b9484cSchristos
14998b9484cSchristos for (page = 0; page < NUMPAGES; page++)
15098b9484cSchristos *(pagetable + page) = NULL;
15198b9484cSchristos
15298b9484cSchristos state->MemDataPtr = (unsigned char *) pagetable;
15398b9484cSchristos
15498b9484cSchristos ARMul_ConsolePrint (state, ", 4 Gb memory");
15598b9484cSchristos
15698b9484cSchristos return TRUE;
15798b9484cSchristos }
15898b9484cSchristos
15998b9484cSchristos /***************************************************************************\
16098b9484cSchristos * Remove the memory interface *
16198b9484cSchristos \***************************************************************************/
16298b9484cSchristos
16398b9484cSchristos void
ARMul_MemoryExit(ARMul_State * state)16498b9484cSchristos ARMul_MemoryExit (ARMul_State * state)
16598b9484cSchristos {
16698b9484cSchristos ARMword page;
16798b9484cSchristos ARMword **pagetable;
16898b9484cSchristos ARMword *pageptr;
16998b9484cSchristos
17098b9484cSchristos pagetable = (ARMword **) state->MemDataPtr;
17198b9484cSchristos for (page = 0; page < NUMPAGES; page++)
17298b9484cSchristos {
17398b9484cSchristos pageptr = *(pagetable + page);
17498b9484cSchristos if (pageptr != NULL)
17598b9484cSchristos free ((char *) pageptr);
17698b9484cSchristos }
17798b9484cSchristos free ((char *) pagetable);
17898b9484cSchristos return;
17998b9484cSchristos }
18098b9484cSchristos
18198b9484cSchristos /***************************************************************************\
18298b9484cSchristos * ReLoad Instruction *
18398b9484cSchristos \***************************************************************************/
18498b9484cSchristos
18598b9484cSchristos ARMword
ARMul_ReLoadInstr(ARMul_State * state,ARMword address,ARMword isize)18698b9484cSchristos ARMul_ReLoadInstr (ARMul_State * state, ARMword address, ARMword isize)
18798b9484cSchristos {
18898b9484cSchristos #ifdef ABORTS
18998b9484cSchristos if (address >= LOWABORT && address < HIGHABORT)
19098b9484cSchristos {
19198b9484cSchristos ARMul_PREFETCHABORT (address);
19298b9484cSchristos return ARMul_ABORTWORD;
19398b9484cSchristos }
19498b9484cSchristos else
19598b9484cSchristos {
19698b9484cSchristos ARMul_CLEARABORT;
19798b9484cSchristos }
19898b9484cSchristos #endif
19998b9484cSchristos
20098b9484cSchristos if ((isize == 2) && (address & 0x2))
20198b9484cSchristos {
20298b9484cSchristos /* We return the next two halfwords: */
20398b9484cSchristos ARMword lo = GetWord (state, address, FALSE);
20498b9484cSchristos ARMword hi = GetWord (state, address + 4, FALSE);
20598b9484cSchristos
20698b9484cSchristos if (state->bigendSig == HIGH)
20798b9484cSchristos return (lo << 16) | (hi >> 16);
20898b9484cSchristos else
20998b9484cSchristos return ((hi & 0xFFFF) << 16) | (lo >> 16);
21098b9484cSchristos }
21198b9484cSchristos
21298b9484cSchristos return GetWord (state, address, TRUE);
21398b9484cSchristos }
21498b9484cSchristos
21598b9484cSchristos /***************************************************************************\
21698b9484cSchristos * Load Instruction, Sequential Cycle *
21798b9484cSchristos \***************************************************************************/
21898b9484cSchristos
ARMul_LoadInstrS(ARMul_State * state,ARMword address,ARMword isize)21998b9484cSchristos ARMword ARMul_LoadInstrS (ARMul_State * state, ARMword address, ARMword isize)
22098b9484cSchristos {
22198b9484cSchristos state->NumScycles++;
22298b9484cSchristos
22398b9484cSchristos return ARMul_ReLoadInstr (state, address, isize);
22498b9484cSchristos }
22598b9484cSchristos
22698b9484cSchristos /***************************************************************************\
22798b9484cSchristos * Load Instruction, Non Sequential Cycle *
22898b9484cSchristos \***************************************************************************/
22998b9484cSchristos
ARMul_LoadInstrN(ARMul_State * state,ARMword address,ARMword isize)23098b9484cSchristos ARMword ARMul_LoadInstrN (ARMul_State * state, ARMword address, ARMword isize)
23198b9484cSchristos {
23298b9484cSchristos state->NumNcycles++;
23398b9484cSchristos
23498b9484cSchristos return ARMul_ReLoadInstr (state, address, isize);
23598b9484cSchristos }
23698b9484cSchristos
23798b9484cSchristos /***************************************************************************\
23898b9484cSchristos * Read Word (but don't tell anyone!) *
23998b9484cSchristos \***************************************************************************/
24098b9484cSchristos
ARMul_ReadWord(ARMul_State * state,ARMword address)24198b9484cSchristos ARMword ARMul_ReadWord (ARMul_State * state, ARMword address)
24298b9484cSchristos {
24398b9484cSchristos #ifdef ABORTS
24498b9484cSchristos if (address >= LOWABORT && address < HIGHABORT)
24598b9484cSchristos {
24698b9484cSchristos ARMul_DATAABORT (address);
24798b9484cSchristos return ARMul_ABORTWORD;
24898b9484cSchristos }
24998b9484cSchristos else
25098b9484cSchristos {
25198b9484cSchristos ARMul_CLEARABORT;
25298b9484cSchristos }
25398b9484cSchristos #endif
25498b9484cSchristos
25598b9484cSchristos return GetWord (state, address, TRUE);
25698b9484cSchristos }
25798b9484cSchristos
25898b9484cSchristos /***************************************************************************\
25998b9484cSchristos * Load Word, Sequential Cycle *
26098b9484cSchristos \***************************************************************************/
26198b9484cSchristos
ARMul_LoadWordS(ARMul_State * state,ARMword address)26298b9484cSchristos ARMword ARMul_LoadWordS (ARMul_State * state, ARMword address)
26398b9484cSchristos {
26498b9484cSchristos state->NumScycles++;
26598b9484cSchristos
26698b9484cSchristos return ARMul_ReadWord (state, address);
26798b9484cSchristos }
26898b9484cSchristos
26998b9484cSchristos /***************************************************************************\
27098b9484cSchristos * Load Word, Non Sequential Cycle *
27198b9484cSchristos \***************************************************************************/
27298b9484cSchristos
ARMul_LoadWordN(ARMul_State * state,ARMword address)27398b9484cSchristos ARMword ARMul_LoadWordN (ARMul_State * state, ARMword address)
27498b9484cSchristos {
27598b9484cSchristos state->NumNcycles++;
27698b9484cSchristos
27798b9484cSchristos return ARMul_ReadWord (state, address);
27898b9484cSchristos }
27998b9484cSchristos
28098b9484cSchristos /***************************************************************************\
28198b9484cSchristos * Load Halfword, (Non Sequential Cycle) *
28298b9484cSchristos \***************************************************************************/
28398b9484cSchristos
ARMul_LoadHalfWord(ARMul_State * state,ARMword address)28498b9484cSchristos ARMword ARMul_LoadHalfWord (ARMul_State * state, ARMword address)
28598b9484cSchristos {
28698b9484cSchristos ARMword temp, offset;
28798b9484cSchristos
28898b9484cSchristos state->NumNcycles++;
28998b9484cSchristos
29098b9484cSchristos temp = ARMul_ReadWord (state, address);
29198b9484cSchristos offset = (((ARMword) state->bigendSig * 2) ^ (address & 2)) << 3; /* bit offset into the word */
29298b9484cSchristos
29398b9484cSchristos return (temp >> offset) & 0xffff;
29498b9484cSchristos }
29598b9484cSchristos
29698b9484cSchristos /***************************************************************************\
29798b9484cSchristos * Read Byte (but don't tell anyone!) *
29898b9484cSchristos \***************************************************************************/
29998b9484cSchristos
ARMul_ReadByte(ARMul_State * state,ARMword address)30098b9484cSchristos ARMword ARMul_ReadByte (ARMul_State * state, ARMword address)
30198b9484cSchristos {
30298b9484cSchristos ARMword temp, offset;
30398b9484cSchristos
30498b9484cSchristos temp = ARMul_ReadWord (state, address);
30598b9484cSchristos offset = (((ARMword) state->bigendSig * 3) ^ (address & 3)) << 3; /* bit offset into the word */
30698b9484cSchristos
30798b9484cSchristos return (temp >> offset & 0xffL);
30898b9484cSchristos }
30998b9484cSchristos
31098b9484cSchristos /***************************************************************************\
31198b9484cSchristos * Load Byte, (Non Sequential Cycle) *
31298b9484cSchristos \***************************************************************************/
31398b9484cSchristos
ARMul_LoadByte(ARMul_State * state,ARMword address)31498b9484cSchristos ARMword ARMul_LoadByte (ARMul_State * state, ARMword address)
31598b9484cSchristos {
31698b9484cSchristos state->NumNcycles++;
31798b9484cSchristos
31898b9484cSchristos return ARMul_ReadByte (state, address);
31998b9484cSchristos }
32098b9484cSchristos
32198b9484cSchristos /***************************************************************************\
32298b9484cSchristos * Write Word (but don't tell anyone!) *
32398b9484cSchristos \***************************************************************************/
32498b9484cSchristos
32598b9484cSchristos void
ARMul_WriteWord(ARMul_State * state,ARMword address,ARMword data)32698b9484cSchristos ARMul_WriteWord (ARMul_State * state, ARMword address, ARMword data)
32798b9484cSchristos {
32898b9484cSchristos #ifdef ABORTS
32998b9484cSchristos if (address >= LOWABORT && address < HIGHABORT)
33098b9484cSchristos {
33198b9484cSchristos ARMul_DATAABORT (address);
33298b9484cSchristos return;
33398b9484cSchristos }
33498b9484cSchristos else
33598b9484cSchristos {
33698b9484cSchristos ARMul_CLEARABORT;
33798b9484cSchristos }
33898b9484cSchristos #endif
33998b9484cSchristos
34098b9484cSchristos PutWord (state, address, data, TRUE);
34198b9484cSchristos }
34298b9484cSchristos
34398b9484cSchristos /***************************************************************************\
34498b9484cSchristos * Store Word, Sequential Cycle *
34598b9484cSchristos \***************************************************************************/
34698b9484cSchristos
34798b9484cSchristos void
ARMul_StoreWordS(ARMul_State * state,ARMword address,ARMword data)34898b9484cSchristos ARMul_StoreWordS (ARMul_State * state, ARMword address, ARMword data)
34998b9484cSchristos {
35098b9484cSchristos state->NumScycles++;
35198b9484cSchristos
35298b9484cSchristos ARMul_WriteWord (state, address, data);
35398b9484cSchristos }
35498b9484cSchristos
35598b9484cSchristos /***************************************************************************\
35698b9484cSchristos * Store Word, Non Sequential Cycle *
35798b9484cSchristos \***************************************************************************/
35898b9484cSchristos
35998b9484cSchristos void
ARMul_StoreWordN(ARMul_State * state,ARMword address,ARMword data)36098b9484cSchristos ARMul_StoreWordN (ARMul_State * state, ARMword address, ARMword data)
36198b9484cSchristos {
36298b9484cSchristos state->NumNcycles++;
36398b9484cSchristos
36498b9484cSchristos ARMul_WriteWord (state, address, data);
36598b9484cSchristos }
36698b9484cSchristos
36798b9484cSchristos /***************************************************************************\
36898b9484cSchristos * Store HalfWord, (Non Sequential Cycle) *
36998b9484cSchristos \***************************************************************************/
37098b9484cSchristos
37198b9484cSchristos void
ARMul_StoreHalfWord(ARMul_State * state,ARMword address,ARMword data)37298b9484cSchristos ARMul_StoreHalfWord (ARMul_State * state, ARMword address, ARMword data)
37398b9484cSchristos {
37498b9484cSchristos ARMword temp, offset;
37598b9484cSchristos
37698b9484cSchristos state->NumNcycles++;
37798b9484cSchristos
37898b9484cSchristos #ifdef VALIDATE
37998b9484cSchristos if (address == TUBE)
38098b9484cSchristos {
38198b9484cSchristos if (data == 4)
38298b9484cSchristos state->Emulate = FALSE;
38398b9484cSchristos else
38498b9484cSchristos (void) putc ((char) data, stderr); /* Write Char */
38598b9484cSchristos return;
38698b9484cSchristos }
38798b9484cSchristos #endif
38898b9484cSchristos
38998b9484cSchristos temp = ARMul_ReadWord (state, address);
39098b9484cSchristos offset = (((ARMword) state->bigendSig * 2) ^ (address & 2)) << 3; /* bit offset into the word */
39198b9484cSchristos
39298b9484cSchristos PutWord (state, address,
39398b9484cSchristos (temp & ~(0xffffL << offset)) | ((data & 0xffffL) << offset),
39498b9484cSchristos TRUE);
39598b9484cSchristos }
39698b9484cSchristos
39798b9484cSchristos /***************************************************************************\
39898b9484cSchristos * Write Byte (but don't tell anyone!) *
39998b9484cSchristos \***************************************************************************/
40098b9484cSchristos
40198b9484cSchristos void
ARMul_WriteByte(ARMul_State * state,ARMword address,ARMword data)40298b9484cSchristos ARMul_WriteByte (ARMul_State * state, ARMword address, ARMword data)
40398b9484cSchristos {
40498b9484cSchristos ARMword temp, offset;
40598b9484cSchristos
40698b9484cSchristos temp = ARMul_ReadWord (state, address);
40798b9484cSchristos offset = (((ARMword) state->bigendSig * 3) ^ (address & 3)) << 3; /* bit offset into the word */
40898b9484cSchristos
40998b9484cSchristos PutWord (state, address,
41098b9484cSchristos (temp & ~(0xffL << offset)) | ((data & 0xffL) << offset),
41198b9484cSchristos TRUE);
41298b9484cSchristos }
41398b9484cSchristos
41498b9484cSchristos /***************************************************************************\
41598b9484cSchristos * Store Byte, (Non Sequential Cycle) *
41698b9484cSchristos \***************************************************************************/
41798b9484cSchristos
41898b9484cSchristos void
ARMul_StoreByte(ARMul_State * state,ARMword address,ARMword data)41998b9484cSchristos ARMul_StoreByte (ARMul_State * state, ARMword address, ARMword data)
42098b9484cSchristos {
42198b9484cSchristos state->NumNcycles++;
42298b9484cSchristos
42398b9484cSchristos #ifdef VALIDATE
42498b9484cSchristos if (address == TUBE)
42598b9484cSchristos {
42698b9484cSchristos if (data == 4)
42798b9484cSchristos state->Emulate = FALSE;
42898b9484cSchristos else
42998b9484cSchristos (void) putc ((char) data, stderr); /* Write Char */
43098b9484cSchristos return;
43198b9484cSchristos }
43298b9484cSchristos #endif
43398b9484cSchristos
43498b9484cSchristos ARMul_WriteByte (state, address, data);
43598b9484cSchristos }
43698b9484cSchristos
43798b9484cSchristos /***************************************************************************\
43898b9484cSchristos * Swap Word, (Two Non Sequential Cycles) *
43998b9484cSchristos \***************************************************************************/
44098b9484cSchristos
ARMul_SwapWord(ARMul_State * state,ARMword address,ARMword data)44198b9484cSchristos ARMword ARMul_SwapWord (ARMul_State * state, ARMword address, ARMword data)
44298b9484cSchristos {
44398b9484cSchristos ARMword temp;
44498b9484cSchristos
44598b9484cSchristos state->NumNcycles++;
44698b9484cSchristos
44798b9484cSchristos temp = ARMul_ReadWord (state, address);
44898b9484cSchristos
44998b9484cSchristos state->NumNcycles++;
45098b9484cSchristos
45198b9484cSchristos PutWord (state, address, data, TRUE);
45298b9484cSchristos
45398b9484cSchristos return temp;
45498b9484cSchristos }
45598b9484cSchristos
45698b9484cSchristos /***************************************************************************\
45798b9484cSchristos * Swap Byte, (Two Non Sequential Cycles) *
45898b9484cSchristos \***************************************************************************/
45998b9484cSchristos
ARMul_SwapByte(ARMul_State * state,ARMword address,ARMword data)46098b9484cSchristos ARMword ARMul_SwapByte (ARMul_State * state, ARMword address, ARMword data)
46198b9484cSchristos {
46298b9484cSchristos ARMword temp;
46398b9484cSchristos
46498b9484cSchristos temp = ARMul_LoadByte (state, address);
46598b9484cSchristos ARMul_StoreByte (state, address, data);
46698b9484cSchristos
46798b9484cSchristos return temp;
46898b9484cSchristos }
46998b9484cSchristos
47098b9484cSchristos /***************************************************************************\
47198b9484cSchristos * Count I Cycles *
47298b9484cSchristos \***************************************************************************/
47398b9484cSchristos
47498b9484cSchristos void
ARMul_Icycles(ARMul_State * state,unsigned number,ARMword address ATTRIBUTE_UNUSED)47598b9484cSchristos ARMul_Icycles (ARMul_State * state, unsigned number, ARMword address ATTRIBUTE_UNUSED)
47698b9484cSchristos {
47798b9484cSchristos state->NumIcycles += number;
47898b9484cSchristos ARMul_CLEARABORT;
47998b9484cSchristos }
48098b9484cSchristos
48198b9484cSchristos /***************************************************************************\
48298b9484cSchristos * Count C Cycles *
48398b9484cSchristos \***************************************************************************/
48498b9484cSchristos
48598b9484cSchristos void
ARMul_Ccycles(ARMul_State * state,unsigned number,ARMword address ATTRIBUTE_UNUSED)48698b9484cSchristos ARMul_Ccycles (ARMul_State * state, unsigned number, ARMword address ATTRIBUTE_UNUSED)
48798b9484cSchristos {
48898b9484cSchristos state->NumCcycles += number;
48998b9484cSchristos ARMul_CLEARABORT;
49098b9484cSchristos }
49198b9484cSchristos
49298b9484cSchristos
49398b9484cSchristos /* Read a byte. Do not check for alignment or access errors. */
49498b9484cSchristos
49598b9484cSchristos ARMword
ARMul_SafeReadByte(ARMul_State * state,ARMword address)49698b9484cSchristos ARMul_SafeReadByte (ARMul_State * state, ARMword address)
49798b9484cSchristos {
49898b9484cSchristos ARMword temp, offset;
49998b9484cSchristos
50098b9484cSchristos temp = GetWord (state, address, FALSE);
50198b9484cSchristos offset = (((ARMword) state->bigendSig * 3) ^ (address & 3)) << 3;
50298b9484cSchristos
50398b9484cSchristos return (temp >> offset & 0xffL);
50498b9484cSchristos }
50598b9484cSchristos
50698b9484cSchristos void
ARMul_SafeWriteByte(ARMul_State * state,ARMword address,ARMword data)50798b9484cSchristos ARMul_SafeWriteByte (ARMul_State * state, ARMword address, ARMword data)
50898b9484cSchristos {
50998b9484cSchristos ARMword temp, offset;
51098b9484cSchristos
51198b9484cSchristos temp = GetWord (state, address, FALSE);
51298b9484cSchristos offset = (((ARMword) state->bigendSig * 3) ^ (address & 3)) << 3;
51398b9484cSchristos
51498b9484cSchristos PutWord (state, address,
51598b9484cSchristos (temp & ~(0xffL << offset)) | ((data & 0xffL) << offset),
51698b9484cSchristos FALSE);
51798b9484cSchristos }
518