/[qemu]/qemu/target-sparc/op_helper.c
ViewVC logotype

Diff of /qemu/target-sparc/op_helper.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.3 by bellard, Sun Oct 10 17:46:24 2004 UTC revision 1.4 by bellard, Sun Dec 19 23:18:01 2004 UTC
# Line 2  Line 2 
2  #include <fenv.h>  #include <fenv.h>
3  #include "exec.h"  #include "exec.h"
4    
5    //#define DEBUG_MMU
6    
7  #ifdef USE_INT_TO_FLOAT_HELPERS  #ifdef USE_INT_TO_FLOAT_HELPERS
8  void do_fitos(void)  void do_fitos(void)
9  {  {
# Line 33  void do_fcmps (void) Line 35  void do_fcmps (void)
35  {  {
36      if (isnan(FT0) || isnan(FT1)) {      if (isnan(FT0) || isnan(FT1)) {
37          T0 = FSR_FCC1 | FSR_FCC0;          T0 = FSR_FCC1 | FSR_FCC0;
38            env->fsr &= ~(FSR_FCC1 | FSR_FCC0);
39            env->fsr |= T0;
40            if (env->fsr & FSR_NVM) {
41                raise_exception(TT_FP_EXCP);
42            } else {
43                env->fsr |= FSR_NVA;
44            }
45      } else if (FT0 < FT1) {      } else if (FT0 < FT1) {
46          T0 = FSR_FCC0;          T0 = FSR_FCC0;
47      } else if (FT0 > FT1) {      } else if (FT0 > FT1) {
# Line 47  void do_fcmpd (void) Line 56  void do_fcmpd (void)
56  {  {
57      if (isnan(DT0) || isnan(DT1)) {      if (isnan(DT0) || isnan(DT1)) {
58          T0 = FSR_FCC1 | FSR_FCC0;          T0 = FSR_FCC1 | FSR_FCC0;
59            env->fsr &= ~(FSR_FCC1 | FSR_FCC0);
60            env->fsr |= T0;
61            if (env->fsr & FSR_NVM) {
62                raise_exception(TT_FP_EXCP);
63            } else {
64                env->fsr |= FSR_NVA;
65            }
66      } else if (DT0 < DT1) {      } else if (DT0 < DT1) {
67          T0 = FSR_FCC0;          T0 = FSR_FCC0;
68      } else if (DT0 > DT1) {      } else if (DT0 > DT1) {
# Line 59  void do_fcmpd (void) Line 75  void do_fcmpd (void)
75    
76  void helper_ld_asi(int asi, int size, int sign)  void helper_ld_asi(int asi, int size, int sign)
77  {  {
78      switch(asi) {      uint32_t ret;
79    
80        switch (asi) {
81      case 3: /* MMU probe */      case 3: /* MMU probe */
82          T1 = 0;          {
83          return;              int mmulev;
84    
85                mmulev = (T0 >> 8) & 15;
86                if (mmulev > 4)
87                    ret = 0;
88                else {
89                    ret = mmu_probe(T0, mmulev);
90                    //bswap32s(&ret);
91                }
92    #ifdef DEBUG_MMU
93                printf("mmu_probe: 0x%08x (lev %d) -> 0x%08x\n", T0, mmulev, ret);
94    #endif
95            }
96            break;
97      case 4: /* read MMU regs */      case 4: /* read MMU regs */
98          {          {
99              int temp, reg = (T0 >> 8) & 0xf;              int reg = (T0 >> 8) & 0xf;
100                            
101              temp = env->mmuregs[reg];              ret = env->mmuregs[reg];
102              if (reg == 3 || reg == 4) /* Fault status, addr cleared on read*/              if (reg == 3 || reg == 4) /* Fault status, addr cleared on read*/
103                  env->mmuregs[reg] = 0;                  env->mmuregs[4] = 0;
             T1 = temp;  
104          }          }
105          return;          break;
106      case 0x20 ... 0x2f: /* MMU passthrough */      case 0x20 ... 0x2f: /* MMU passthrough */
107          {          cpu_physical_memory_read(T0, (void *) &ret, size);
108              int temp;          if (size == 4)
109                            bswap32s(&ret);
110              cpu_physical_memory_read(T0, (void *) &temp, size);          else if (size == 2)
111              bswap32s(&temp);              bswap16s(&ret);
112              T1 = temp;          break;
         }  
         return;  
113      default:      default:
114          T1 = 0;          ret = 0;
115          return;          break;
116      }      }
117        T1 = ret;
118  }  }
119    
120  void helper_st_asi(int asi, int size, int sign)  void helper_st_asi(int asi, int size, int sign)
121  {  {
122      switch(asi) {      switch(asi) {
123      case 3: /* MMU flush */      case 3: /* MMU flush */
124          return;          {
125                int mmulev;
126    
127                mmulev = (T0 >> 8) & 15;
128                switch (mmulev) {
129                case 0: // flush page
130                    tlb_flush_page(cpu_single_env, T0 & 0xfffff000);
131                    break;
132                case 1: // flush segment (256k)
133                case 2: // flush region (16M)
134                case 3: // flush context (4G)
135                case 4: // flush entire
136                    tlb_flush(cpu_single_env, 1);
137                    break;
138                default:
139                    break;
140                }
141                dump_mmu();
142                return;
143            }
144      case 4: /* write MMU regs */      case 4: /* write MMU regs */
145          {          {
146              int reg = (T0 >> 8) & 0xf;              int reg = (T0 >> 8) & 0xf, oldreg;
147                
148                oldreg = env->mmuregs[reg];
149              if (reg == 0) {              if (reg == 0) {
150                  env->mmuregs[reg] &= ~(MMU_E | MMU_NF);                  env->mmuregs[reg] &= ~(MMU_E | MMU_NF);
151                  env->mmuregs[reg] |= T1 & (MMU_E | MMU_NF);                  env->mmuregs[reg] |= T1 & (MMU_E | MMU_NF);
152              } else              } else
153                  env->mmuregs[reg] = T1;                  env->mmuregs[reg] = T1;
154                if (oldreg != env->mmuregs[reg]) {
155    #if 0
156                    // XXX: Only if MMU mapping change, we may need to flush?
157                    tlb_flush(cpu_single_env, 1);
158                    cpu_loop_exit();
159                    FORCE_RET();
160    #endif
161                }
162                dump_mmu();
163              return;              return;
164          }          }
165        case 0x17: /* Block copy, sta access */
166            {
167                // value (T1) = src
168                // address (T0) = dst
169                // copy 32 bytes
170                int src = T1, dst = T0;
171                uint8_t temp[32];
172                
173                bswap32s(&src);
174    
175                cpu_physical_memory_read(src, (void *) &temp, 32);
176                cpu_physical_memory_write(dst, (void *) &temp, 32);
177            }
178            return;
179        case 0x1f: /* Block fill, stda access */
180            {
181                // value (T1, T2)
182                // address (T0) = dst
183                // fill 32 bytes
184                int i, dst = T0;
185                uint64_t val;
186                
187                val = (((uint64_t)T1) << 32) | T2;
188                bswap64s(&val);
189    
190                for (i = 0; i < 32; i += 8, dst += 8) {
191                    cpu_physical_memory_write(dst, (void *) &val, 8);
192                }
193            }
194            return;
195      case 0x20 ... 0x2f: /* MMU passthrough */      case 0x20 ... 0x2f: /* MMU passthrough */
196          {          {
197              int temp = T1;              int temp = T1;
198                            if (size == 4)
199              bswap32s(&temp);                  bswap32s(&temp);
200                else if (size == 2)
201                    bswap16s(&temp);
202    
203              cpu_physical_memory_write(T0, (void *) &temp, size);              cpu_physical_memory_write(T0, (void *) &temp, size);
204          }          }
205          return;          return;
# Line 116  void helper_st_asi(int asi, int size, in Line 208  void helper_st_asi(int asi, int size, in
208      }      }
209  }  }
210    
 #if 0  
 void do_ldd_raw(uint32_t addr)  
 {  
     T1 = ldl_raw((void *) addr);  
     T0 = ldl_raw((void *) (addr + 4));  
 }  
   
 #if !defined(CONFIG_USER_ONLY)  
 void do_ldd_user(uint32_t addr)  
 {  
     T1 = ldl_user((void *) addr);  
     T0 = ldl_user((void *) (addr + 4));  
 }  
 void do_ldd_kernel(uint32_t addr)  
 {  
     T1 = ldl_kernel((void *) addr);  
     T0 = ldl_kernel((void *) (addr + 4));  
 }  
 #endif  
 #endif  
   
211  void helper_rett()  void helper_rett()
212  {  {
213      int cwp;      int cwp;
# Line 166  void helper_ldfsr(void) Line 237  void helper_ldfsr(void)
237          break;          break;
238      }      }
239  }  }
240    
241    void cpu_get_fp64(uint64_t *pmant, uint16_t *pexp, double f)
242    {
243        int exptemp;
244    
245        *pmant = ldexp(frexp(f, &exptemp), 53);
246        *pexp = exptemp;
247    }
248    
249    double cpu_put_fp64(uint64_t mant, uint16_t exp)
250    {
251        return ldexp((double) mant, exp - 53);
252    }
253    
254    void helper_debug()
255    {
256        env->exception_index = EXCP_DEBUG;
257        cpu_loop_exit();
258    }

Legend:
Removed from v.1.3  
changed lines
  Added in v.1.4

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26