target-mips: make CP0_LLAddr register CPU dependent
authorAurelien Jarno <aurelien@aurel32.net>
Sun, 22 Nov 2009 12:22:54 +0000 (13:22 +0100)
committerAurelien Jarno <aurelien@aurel32.net>
Sun, 22 Nov 2009 13:12:19 +0000 (14:12 +0100)
Depending on the CPU, CP0_LLAddr is either read-only or read-write,
and the returned value can be shifted by a variable amount of bits.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
target-mips/cpu.h
target-mips/helper.h
target-mips/op_helper.c
target-mips/translate.c
target-mips/translate_init.c

index 45f3987317ecd5a73c4b07b2dcbbba8064775556..5287e9a90faecd6ddd390b114aee64ab184622e0 100644 (file)
@@ -376,6 +376,8 @@ struct CPUMIPSState {
     target_ulong llval;
     target_ulong llnewval;
     target_ulong llreg;
+    target_ulong CP0_LLAddr_rw_bitmask;
+    int CP0_LLAddr_shift;
     target_ulong CP0_WatchLo[8];
     int32_t CP0_WatchHi[8];
     target_ulong CP0_XContext;
index b8ec15eab2af6f7e1b62a6e8301a81245633b975..4f1de5193f86bd8965ccbd7e516492acfa8e7b00 100644 (file)
@@ -122,6 +122,7 @@ DEF_HELPER_1(mtc0_cause, void, tl)
 DEF_HELPER_1(mtc0_ebase, void, tl)
 DEF_HELPER_1(mtc0_config0, void, tl)
 DEF_HELPER_1(mtc0_config2, void, tl)
+DEF_HELPER_1(mtc0_lladdr, void, tl)
 DEF_HELPER_2(mtc0_watchlo, void, tl, i32)
 DEF_HELPER_2(mtc0_watchhi, void, tl, i32)
 DEF_HELPER_1(mtc0_xcontext, void, tl)
index d2a81f08b4819128f88ef39105183a8b1bd74e58..52d687d3373ca39f70d896bb41b1a1fe59a3083c 100644 (file)
@@ -730,7 +730,7 @@ target_ulong helper_mftc0_status(void)
 
 target_ulong helper_mfc0_lladdr (void)
 {
-    return (int32_t)env->lladdr >> 4;
+    return (int32_t)(env->lladdr >> env->CP0_LLAddr_shift);
 }
 
 target_ulong helper_mfc0_watchlo (uint32_t sel)
@@ -795,7 +795,7 @@ target_ulong helper_dmfc0_tcschefback (void)
 
 target_ulong helper_dmfc0_lladdr (void)
 {
-    return env->lladdr >> 4;
+    return env->lladdr >> env->CP0_LLAddr_shift;
 }
 
 target_ulong helper_dmfc0_watchlo (uint32_t sel)
@@ -1243,6 +1243,13 @@ void helper_mtc0_config2 (target_ulong arg1)
     env->CP0_Config2 = (env->CP0_Config2 & 0x8FFF0FFF);
 }
 
+void helper_mtc0_lladdr (target_ulong arg1)
+{
+    target_long mask = env->CP0_LLAddr_rw_bitmask;
+    arg1 = arg1 << env->CP0_LLAddr_shift;
+    env->lladdr = (env->lladdr & ~mask) | (arg1 & mask);
+}
+
 void helper_mtc0_watchlo (target_ulong arg1, uint32_t sel)
 {
     /* Watch exceptions for instructions, data loads, data stores
index 63737e2379b1980c93a32ef1c8d98bdd73e8f8a9..e9d92249ef7e7dec6b1b363f93f4fe4da86fa994 100644 (file)
@@ -3841,7 +3841,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int s
     case 17:
         switch (sel) {
         case 0:
-            /* ignored */
+            gen_helper_mtc0_lladdr(arg);
             rn = "LLAddr";
             break;
         default:
@@ -4998,7 +4998,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int
     case 17:
         switch (sel) {
         case 0:
-            /* ignored */
+            gen_helper_mtc0_lladdr(arg);
             rn = "LLAddr";
             break;
         default:
@@ -8633,6 +8633,9 @@ void cpu_reset (CPUMIPSState *env)
     env->CP0_Config3 = env->cpu_model->CP0_Config3;
     env->CP0_Config6 = env->cpu_model->CP0_Config6;
     env->CP0_Config7 = env->cpu_model->CP0_Config7;
+    env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
+                                 << env->cpu_model->CP0_LLAddr_shift;
+    env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
     env->SYNCI_Step = env->cpu_model->SYNCI_Step;
     env->CCRes = env->cpu_model->CCRes;
     env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
index 088e2b4c29cad5bfa80ef66be5447fa9b552afff..c950eab1adf0efddd17bd0834bb5088b0caa3958 100644 (file)
@@ -70,6 +70,8 @@ struct mips_def_t {
     int32_t CP0_Config3;
     int32_t CP0_Config6;
     int32_t CP0_Config7;
+    target_ulong CP0_LLAddr_rw_bitmask;
+    int CP0_LLAddr_shift;
     int32_t SYNCI_Step;
     int32_t CCRes;
     int32_t CP0_Status_rw_bitmask;
@@ -105,6 +107,8 @@ static const mips_def_t mips_defs[] =
                        (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA),
         .CP0_Config2 = MIPS_CONFIG2,
         .CP0_Config3 = MIPS_CONFIG3,
+        .CP0_LLAddr_rw_bitmask = 0,
+        .CP0_LLAddr_shift = 4,
         .SYNCI_Step = 32,
         .CCRes = 2,
         .CP0_Status_rw_bitmask = 0x1278FF17,
@@ -124,6 +128,8 @@ static const mips_def_t mips_defs[] =
                        (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA),
         .CP0_Config2 = MIPS_CONFIG2,
         .CP0_Config3 = MIPS_CONFIG3,
+        .CP0_LLAddr_rw_bitmask = 0,
+        .CP0_LLAddr_shift = 4,
         .SYNCI_Step = 32,
         .CCRes = 2,
         .CP0_Status_rw_bitmask = 0x1258FF17,
@@ -141,6 +147,8 @@ static const mips_def_t mips_defs[] =
                        (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA),
         .CP0_Config2 = MIPS_CONFIG2,
         .CP0_Config3 = MIPS_CONFIG3,
+        .CP0_LLAddr_rw_bitmask = 0,
+        .CP0_LLAddr_shift = 4,
         .SYNCI_Step = 32,
         .CCRes = 2,
         .CP0_Status_rw_bitmask = 0x1278FF17,
@@ -158,6 +166,8 @@ static const mips_def_t mips_defs[] =
                        (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA),
         .CP0_Config2 = MIPS_CONFIG2,
         .CP0_Config3 = MIPS_CONFIG3,
+        .CP0_LLAddr_rw_bitmask = 0,
+        .CP0_LLAddr_shift = 4,
         .SYNCI_Step = 32,
         .CCRes = 2,
         .CP0_Status_rw_bitmask = 0x1258FF17,
@@ -176,6 +186,8 @@ static const mips_def_t mips_defs[] =
                        (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA),
         .CP0_Config2 = MIPS_CONFIG2,
         .CP0_Config3 = MIPS_CONFIG3 | (0 << CP0C3_VInt),
+        .CP0_LLAddr_rw_bitmask = 0,
+        .CP0_LLAddr_shift = 4,
         .SYNCI_Step = 32,
         .CCRes = 2,
         .CP0_Status_rw_bitmask = 0x1278FF17,
@@ -194,6 +206,8 @@ static const mips_def_t mips_defs[] =
                        (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA),
         .CP0_Config2 = MIPS_CONFIG2,
         .CP0_Config3 = MIPS_CONFIG3,
+        .CP0_LLAddr_rw_bitmask = 0,
+        .CP0_LLAddr_shift = 4,
         .SYNCI_Step = 32,
         .CCRes = 2,
         .CP0_Status_rw_bitmask = 0x1258FF17,
@@ -212,6 +226,8 @@ static const mips_def_t mips_defs[] =
                        (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA),
         .CP0_Config2 = MIPS_CONFIG2,
         .CP0_Config3 = MIPS_CONFIG3 | (0 << CP0C3_VInt),
+        .CP0_LLAddr_rw_bitmask = 0,
+        .CP0_LLAddr_shift = 4,
         .SYNCI_Step = 32,
         .CCRes = 2,
         /* No DSP implemented. */
@@ -231,6 +247,8 @@ static const mips_def_t mips_defs[] =
                        (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA),
         .CP0_Config2 = MIPS_CONFIG2,
         .CP0_Config3 = MIPS_CONFIG3 | (0 << CP0C3_VInt),
+        .CP0_LLAddr_rw_bitmask = 0,
+        .CP0_LLAddr_shift = 4,
         .SYNCI_Step = 32,
         .CCRes = 2,
         /* No DSP implemented. */
@@ -252,6 +270,8 @@ static const mips_def_t mips_defs[] =
                        (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA),
         .CP0_Config2 = MIPS_CONFIG2,
         .CP0_Config3 = MIPS_CONFIG3 | (0 << CP0C3_VInt) | (1 << CP0C3_MT),
+        .CP0_LLAddr_rw_bitmask = 0,
+        .CP0_LLAddr_shift = 0,
         .SYNCI_Step = 32,
         .CCRes = 2,
         /* No DSP implemented. */
@@ -294,6 +314,8 @@ static const mips_def_t mips_defs[] =
         .CP0_Config0 = (1 << 17) | (0x1 << 9) | (0x1 << 6) | (0x2 << CP0C0_K0),
         /* Note: Config1 is only used internally, the R4000 has only Config0. */
         .CP0_Config1 = (1 << CP0C1_FP) | (47 << CP0C1_MMU),
+        .CP0_LLAddr_rw_bitmask = 0xFFFFFFFF,
+        .CP0_LLAddr_shift = 4,
         .SYNCI_Step = 16,
         .CCRes = 2,
         .CP0_Status_rw_bitmask = 0x3678FFFF,
@@ -310,6 +332,8 @@ static const mips_def_t mips_defs[] =
         /* No L2 cache, icache size 8k, dcache size 8k, uncached coherency. */
         .CP0_Config0 = (1 << 17) | (0x1 << 9) | (0x1 << 6) | (0x2 << CP0C0_K0),
         .CP0_Config1 = (1 << CP0C1_FP) | (47 << CP0C1_MMU),
+        .CP0_LLAddr_rw_bitmask = 0xFFFFFFFFL,
+        .CP0_LLAddr_shift = 4,
         .SYNCI_Step = 16,
         .CCRes = 2,
         .CP0_Status_rw_bitmask = 0x3678FFFF,
@@ -331,6 +355,8 @@ static const mips_def_t mips_defs[] =
                        (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP),
         .CP0_Config2 = MIPS_CONFIG2,
         .CP0_Config3 = MIPS_CONFIG3,
+        .CP0_LLAddr_rw_bitmask = 0,
+        .CP0_LLAddr_shift = 4,
         .SYNCI_Step = 32,
         .CCRes = 2,
         .CP0_Status_rw_bitmask = 0x32F8FFFF,
@@ -350,6 +376,8 @@ static const mips_def_t mips_defs[] =
                        (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP),
         .CP0_Config2 = MIPS_CONFIG2,
         .CP0_Config3 = MIPS_CONFIG3,
+        .CP0_LLAddr_rw_bitmask = 0,
+        .CP0_LLAddr_shift = 4,
         .SYNCI_Step = 32,
         .CCRes = 2,
         .CP0_Status_rw_bitmask = 0x36F8FFFF,
@@ -374,6 +402,8 @@ static const mips_def_t mips_defs[] =
                        (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP),
         .CP0_Config2 = MIPS_CONFIG2,
         .CP0_Config3 = MIPS_CONFIG3,
+        .CP0_LLAddr_rw_bitmask = 0,
+        .CP0_LLAddr_shift = 0,
         .SYNCI_Step = 32,
         .CCRes = 1,
         .CP0_Status_rw_bitmask = 0x36FBFFFF,
@@ -399,6 +429,8 @@ static const mips_def_t mips_defs[] =
                        (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP),
         .CP0_Config2 = MIPS_CONFIG2,
         .CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_LPA),
+        .CP0_LLAddr_rw_bitmask = 0,
+        .CP0_LLAddr_shift = 0,
         .SYNCI_Step = 32,
         .CCRes = 2,
         .CP0_Status_rw_bitmask = 0x36FBFFFF,