Commit 2c0262afa75d7d6cb68217f9a7587170ed3cd5b3
1 parent
196ad109
new directory structure
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@385 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
11 changed files
with
3326 additions
and
0 deletions
Too many changes to show.
To preserve performance only 11 of 19 files are displayed.
linux-user/arm/syscall.h
0 → 100644
| 1 | + | ||
| 2 | +/* this struct defines the way the registers are stored on the | ||
| 3 | + stack during a system call. */ | ||
| 4 | + | ||
| 5 | +struct target_pt_regs { | ||
| 6 | + target_long uregs[18]; | ||
| 7 | +}; | ||
| 8 | + | ||
| 9 | +#define ARM_cpsr uregs[16] | ||
| 10 | +#define ARM_pc uregs[15] | ||
| 11 | +#define ARM_lr uregs[14] | ||
| 12 | +#define ARM_sp uregs[13] | ||
| 13 | +#define ARM_ip uregs[12] | ||
| 14 | +#define ARM_fp uregs[11] | ||
| 15 | +#define ARM_r10 uregs[10] | ||
| 16 | +#define ARM_r9 uregs[9] | ||
| 17 | +#define ARM_r8 uregs[8] | ||
| 18 | +#define ARM_r7 uregs[7] | ||
| 19 | +#define ARM_r6 uregs[6] | ||
| 20 | +#define ARM_r5 uregs[5] | ||
| 21 | +#define ARM_r4 uregs[4] | ||
| 22 | +#define ARM_r3 uregs[3] | ||
| 23 | +#define ARM_r2 uregs[2] | ||
| 24 | +#define ARM_r1 uregs[1] | ||
| 25 | +#define ARM_r0 uregs[0] | ||
| 26 | +#define ARM_ORIG_r0 uregs[17] | ||
| 27 | + | ||
| 28 | +#define ARM_SYSCALL_BASE 0x900000 |
linux-user/arm/syscall_nr.h
0 → 100644
| 1 | +/* | ||
| 2 | + * This file contains the system call numbers. | ||
| 3 | + */ | ||
| 4 | + | ||
| 5 | +#define TARGET_NR_restart_syscall ( 0) | ||
| 6 | +#define TARGET_NR_exit ( 1) | ||
| 7 | +#define TARGET_NR_fork ( 2) | ||
| 8 | +#define TARGET_NR_read ( 3) | ||
| 9 | +#define TARGET_NR_write ( 4) | ||
| 10 | +#define TARGET_NR_open ( 5) | ||
| 11 | +#define TARGET_NR_close ( 6) | ||
| 12 | +#define TARGET_NR_waitpid ( 7) /* removed */ | ||
| 13 | +#define TARGET_NR_creat ( 8) | ||
| 14 | +#define TARGET_NR_link ( 9) | ||
| 15 | +#define TARGET_NR_unlink ( 10) | ||
| 16 | +#define TARGET_NR_execve ( 11) | ||
| 17 | +#define TARGET_NR_chdir ( 12) | ||
| 18 | +#define TARGET_NR_time ( 13) | ||
| 19 | +#define TARGET_NR_mknod ( 14) | ||
| 20 | +#define TARGET_NR_chmod ( 15) | ||
| 21 | +#define TARGET_NR_lchown ( 16) | ||
| 22 | +#define TARGET_NR_break ( 17) /* removed */ | ||
| 23 | + /* 18 was sys_stat */ | ||
| 24 | +#define TARGET_NR_lseek ( 19) | ||
| 25 | +#define TARGET_NR_getpid ( 20) | ||
| 26 | +#define TARGET_NR_mount ( 21) | ||
| 27 | +#define TARGET_NR_umount ( 22) | ||
| 28 | +#define TARGET_NR_setuid ( 23) | ||
| 29 | +#define TARGET_NR_getuid ( 24) | ||
| 30 | +#define TARGET_NR_stime ( 25) | ||
| 31 | +#define TARGET_NR_ptrace ( 26) | ||
| 32 | +#define TARGET_NR_alarm ( 27) | ||
| 33 | + | ||
| 34 | +#define TARGET_NR_pause ( 29) | ||
| 35 | +#define TARGET_NR_utime ( 30) | ||
| 36 | +#define TARGET_NR_stty ( 31) /* removed */ | ||
| 37 | +#define TARGET_NR_gtty ( 32) /* removed */ | ||
| 38 | +#define TARGET_NR_access ( 33) | ||
| 39 | +#define TARGET_NR_nice ( 34) | ||
| 40 | +#define TARGET_NR_ftime ( 35) /* removed */ | ||
| 41 | +#define TARGET_NR_sync ( 36) | ||
| 42 | +#define TARGET_NR_kill ( 37) | ||
| 43 | +#define TARGET_NR_rename ( 38) | ||
| 44 | +#define TARGET_NR_mkdir ( 39) | ||
| 45 | +#define TARGET_NR_rmdir ( 40) | ||
| 46 | +#define TARGET_NR_dup ( 41) | ||
| 47 | +#define TARGET_NR_pipe ( 42) | ||
| 48 | +#define TARGET_NR_times ( 43) | ||
| 49 | +#define TARGET_NR_prof ( 44) /* removed */ | ||
| 50 | +#define TARGET_NR_brk ( 45) | ||
| 51 | +#define TARGET_NR_setgid ( 46) | ||
| 52 | +#define TARGET_NR_getgid ( 47) | ||
| 53 | +#define TARGET_NR_signal ( 48) /* removed */ | ||
| 54 | +#define TARGET_NR_geteuid ( 49) | ||
| 55 | +#define TARGET_NR_getegid ( 50) | ||
| 56 | +#define TARGET_NR_acct ( 51) | ||
| 57 | +#define TARGET_NR_umount2 ( 52) | ||
| 58 | +#define TARGET_NR_lock ( 53) /* removed */ | ||
| 59 | +#define TARGET_NR_ioctl ( 54) | ||
| 60 | +#define TARGET_NR_fcntl ( 55) | ||
| 61 | +#define TARGET_NR_mpx ( 56) /* removed */ | ||
| 62 | +#define TARGET_NR_setpgid ( 57) | ||
| 63 | +#define TARGET_NR_ulimit ( 58) /* removed */ | ||
| 64 | + /* 59 was sys_olduname */ | ||
| 65 | +#define TARGET_NR_umask ( 60) | ||
| 66 | +#define TARGET_NR_chroot ( 61) | ||
| 67 | +#define TARGET_NR_ustat ( 62) | ||
| 68 | +#define TARGET_NR_dup2 ( 63) | ||
| 69 | +#define TARGET_NR_getppid ( 64) | ||
| 70 | +#define TARGET_NR_getpgrp ( 65) | ||
| 71 | +#define TARGET_NR_setsid ( 66) | ||
| 72 | +#define TARGET_NR_sigaction ( 67) | ||
| 73 | +#define TARGET_NR_sgetmask ( 68) /* removed */ | ||
| 74 | +#define TARGET_NR_ssetmask ( 69) /* removed */ | ||
| 75 | +#define TARGET_NR_setreuid ( 70) | ||
| 76 | +#define TARGET_NR_setregid ( 71) | ||
| 77 | +#define TARGET_NR_sigsuspend ( 72) | ||
| 78 | +#define TARGET_NR_sigpending ( 73) | ||
| 79 | +#define TARGET_NR_sethostname ( 74) | ||
| 80 | +#define TARGET_NR_setrlimit ( 75) | ||
| 81 | +#define TARGET_NR_getrlimit ( 76) /* Back compat 2GB limited rlimit */ | ||
| 82 | +#define TARGET_NR_getrusage ( 77) | ||
| 83 | +#define TARGET_NR_gettimeofday ( 78) | ||
| 84 | +#define TARGET_NR_settimeofday ( 79) | ||
| 85 | +#define TARGET_NR_getgroups ( 80) | ||
| 86 | +#define TARGET_NR_setgroups ( 81) | ||
| 87 | +#define TARGET_NR_select ( 82) | ||
| 88 | +#define TARGET_NR_symlink ( 83) | ||
| 89 | + /* 84 was sys_lstat */ | ||
| 90 | +#define TARGET_NR_readlink ( 85) | ||
| 91 | +#define TARGET_NR_uselib ( 86) | ||
| 92 | +#define TARGET_NR_swapon ( 87) | ||
| 93 | +#define TARGET_NR_reboot ( 88) | ||
| 94 | +#define TARGET_NR_readdir ( 89) | ||
| 95 | +#define TARGET_NR_mmap ( 90) | ||
| 96 | +#define TARGET_NR_munmap ( 91) | ||
| 97 | +#define TARGET_NR_truncate ( 92) | ||
| 98 | +#define TARGET_NR_ftruncate ( 93) | ||
| 99 | +#define TARGET_NR_fchmod ( 94) | ||
| 100 | +#define TARGET_NR_fchown ( 95) | ||
| 101 | +#define TARGET_NR_getpriority ( 96) | ||
| 102 | +#define TARGET_NR_setpriority ( 97) | ||
| 103 | +#define TARGET_NR_profil ( 98) /* removed */ | ||
| 104 | +#define TARGET_NR_statfs ( 99) | ||
| 105 | +#define TARGET_NR_fstatfs (100) | ||
| 106 | +#define TARGET_NR_ioperm (101) | ||
| 107 | +#define TARGET_NR_socketcall (102) | ||
| 108 | +#define TARGET_NR_syslog (103) | ||
| 109 | +#define TARGET_NR_setitimer (104) | ||
| 110 | +#define TARGET_NR_getitimer (105) | ||
| 111 | +#define TARGET_NR_stat (106) | ||
| 112 | +#define TARGET_NR_lstat (107) | ||
| 113 | +#define TARGET_NR_fstat (108) | ||
| 114 | + /* 109 was sys_uname */ | ||
| 115 | + /* 110 was sys_iopl */ | ||
| 116 | +#define TARGET_NR_vhangup (111) | ||
| 117 | +#define TARGET_NR_idle (112) | ||
| 118 | +#define TARGET_NR_syscall (113) /* syscall to call a syscall! */ | ||
| 119 | +#define TARGET_NR_wait4 (114) | ||
| 120 | +#define TARGET_NR_swapoff (115) | ||
| 121 | +#define TARGET_NR_sysinfo (116) | ||
| 122 | +#define TARGET_NR_ipc (117) | ||
| 123 | +#define TARGET_NR_fsync (118) | ||
| 124 | +#define TARGET_NR_sigreturn (119) | ||
| 125 | +#define TARGET_NR_clone (120) | ||
| 126 | +#define TARGET_NR_setdomainname (121) | ||
| 127 | +#define TARGET_NR_uname (122) | ||
| 128 | +#define TARGET_NR_modify_ldt (123) | ||
| 129 | +#define TARGET_NR_adjtimex (124) | ||
| 130 | +#define TARGET_NR_mprotect (125) | ||
| 131 | +#define TARGET_NR_sigprocmask (126) | ||
| 132 | +#define TARGET_NR_create_module (127) /* removed */ | ||
| 133 | +#define TARGET_NR_init_module (128) | ||
| 134 | +#define TARGET_NR_delete_module (129) | ||
| 135 | +#define TARGET_NR_get_kernel_syms (130) /* removed */ | ||
| 136 | +#define TARGET_NR_quotactl (131) | ||
| 137 | +#define TARGET_NR_getpgid (132) | ||
| 138 | +#define TARGET_NR_fchdir (133) | ||
| 139 | +#define TARGET_NR_bdflush (134) | ||
| 140 | +#define TARGET_NR_sysfs (135) | ||
| 141 | +#define TARGET_NR_personality (136) | ||
| 142 | +#define TARGET_NR_afs_syscall (137) /* Syscall for Andrew File System */ | ||
| 143 | +#define TARGET_NR_setfsuid (138) | ||
| 144 | +#define TARGET_NR_setfsgid (139) | ||
| 145 | +#define TARGET_NR__llseek (140) | ||
| 146 | +#define TARGET_NR_getdents (141) | ||
| 147 | +#define TARGET_NR__newselect (142) | ||
| 148 | +#define TARGET_NR_flock (143) | ||
| 149 | +#define TARGET_NR_msync (144) | ||
| 150 | +#define TARGET_NR_readv (145) | ||
| 151 | +#define TARGET_NR_writev (146) | ||
| 152 | +#define TARGET_NR_getsid (147) | ||
| 153 | +#define TARGET_NR_fdatasync (148) | ||
| 154 | +#define TARGET_NR__sysctl (149) | ||
| 155 | +#define TARGET_NR_mlock (150) | ||
| 156 | +#define TARGET_NR_munlock (151) | ||
| 157 | +#define TARGET_NR_mlockall (152) | ||
| 158 | +#define TARGET_NR_munlockall (153) | ||
| 159 | +#define TARGET_NR_sched_setparam (154) | ||
| 160 | +#define TARGET_NR_sched_getparam (155) | ||
| 161 | +#define TARGET_NR_sched_setscheduler (156) | ||
| 162 | +#define TARGET_NR_sched_getscheduler (157) | ||
| 163 | +#define TARGET_NR_sched_yield (158) | ||
| 164 | +#define TARGET_NR_sched_get_priority_max (159) | ||
| 165 | +#define TARGET_NR_sched_get_priority_min (160) | ||
| 166 | +#define TARGET_NR_sched_rr_get_interval (161) | ||
| 167 | +#define TARGET_NR_nanosleep (162) | ||
| 168 | +#define TARGET_NR_mremap (163) | ||
| 169 | +#define TARGET_NR_setresuid (164) | ||
| 170 | +#define TARGET_NR_getresuid (165) | ||
| 171 | +#define TARGET_NR_vm86 (166) /* removed */ | ||
| 172 | +#define TARGET_NR_query_module (167) /* removed */ | ||
| 173 | +#define TARGET_NR_poll (168) | ||
| 174 | +#define TARGET_NR_nfsservctl (169) | ||
| 175 | +#define TARGET_NR_setresgid (170) | ||
| 176 | +#define TARGET_NR_getresgid (171) | ||
| 177 | +#define TARGET_NR_prctl (172) | ||
| 178 | +#define TARGET_NR_rt_sigreturn (173) | ||
| 179 | +#define TARGET_NR_rt_sigaction (174) | ||
| 180 | +#define TARGET_NR_rt_sigprocmask (175) | ||
| 181 | +#define TARGET_NR_rt_sigpending (176) | ||
| 182 | +#define TARGET_NR_rt_sigtimedwait (177) | ||
| 183 | +#define TARGET_NR_rt_sigqueueinfo (178) | ||
| 184 | +#define TARGET_NR_rt_sigsuspend (179) | ||
| 185 | +#define TARGET_NR_pread (180) | ||
| 186 | +#define TARGET_NR_pwrite (181) | ||
| 187 | +#define TARGET_NR_chown (182) | ||
| 188 | +#define TARGET_NR_getcwd (183) | ||
| 189 | +#define TARGET_NR_capget (184) | ||
| 190 | +#define TARGET_NR_capset (185) | ||
| 191 | +#define TARGET_NR_sigaltstack (186) | ||
| 192 | +#define TARGET_NR_sendfile (187) | ||
| 193 | + /* 188 reserved */ | ||
| 194 | + /* 189 reserved */ | ||
| 195 | +#define TARGET_NR_vfork (190) | ||
| 196 | +#define TARGET_NR_ugetrlimit (191) /* SuS compliant getrlimit */ | ||
| 197 | +#define TARGET_NR_mmap2 (192) | ||
| 198 | +#define TARGET_NR_truncate64 (193) | ||
| 199 | +#define TARGET_NR_ftruncate64 (194) | ||
| 200 | +#define TARGET_NR_stat64 (195) | ||
| 201 | +#define TARGET_NR_lstat64 (196) | ||
| 202 | +#define TARGET_NR_fstat64 (197) | ||
| 203 | +#define TARGET_NR_lchown32 (198) | ||
| 204 | +#define TARGET_NR_getuid32 (199) | ||
| 205 | +#define TARGET_NR_getgid32 (200) | ||
| 206 | +#define TARGET_NR_geteuid32 (201) | ||
| 207 | +#define TARGET_NR_getegid32 (202) | ||
| 208 | +#define TARGET_NR_setreuid32 (203) | ||
| 209 | +#define TARGET_NR_setregid32 (204) | ||
| 210 | +#define TARGET_NR_getgroups32 (205) | ||
| 211 | +#define TARGET_NR_setgroups32 (206) | ||
| 212 | +#define TARGET_NR_fchown32 (207) | ||
| 213 | +#define TARGET_NR_setresuid32 (208) | ||
| 214 | +#define TARGET_NR_getresuid32 (209) | ||
| 215 | +#define TARGET_NR_setresgid32 (210) | ||
| 216 | +#define TARGET_NR_getresgid32 (211) | ||
| 217 | +#define TARGET_NR_chown32 (212) | ||
| 218 | +#define TARGET_NR_setuid32 (213) | ||
| 219 | +#define TARGET_NR_setgid32 (214) | ||
| 220 | +#define TARGET_NR_setfsuid32 (215) | ||
| 221 | +#define TARGET_NR_setfsgid32 (216) | ||
| 222 | +#define TARGET_NR_getdents64 (217) | ||
| 223 | +#define TARGET_NR_pivot_root (218) | ||
| 224 | +#define TARGET_NR_mincore (219) | ||
| 225 | +#define TARGET_NR_madvise (220) | ||
| 226 | +#define TARGET_NR_fcntl64 (221) | ||
| 227 | + /* 222 for tux */ | ||
| 228 | + /* 223 is unused */ | ||
| 229 | +#define TARGET_NR_gettid (224) | ||
| 230 | +#define TARGET_NR_readahead (225) | ||
| 231 | +#define TARGET_NR_setxattr (226) | ||
| 232 | +#define TARGET_NR_lsetxattr (227) | ||
| 233 | +#define TARGET_NR_fsetxattr (228) | ||
| 234 | +#define TARGET_NR_getxattr (229) | ||
| 235 | +#define TARGET_NR_lgetxattr (230) | ||
| 236 | +#define TARGET_NR_fgetxattr (231) | ||
| 237 | +#define TARGET_NR_listxattr (232) | ||
| 238 | +#define TARGET_NR_llistxattr (233) | ||
| 239 | +#define TARGET_NR_flistxattr (234) | ||
| 240 | +#define TARGET_NR_removexattr (235) | ||
| 241 | +#define TARGET_NR_lremovexattr (236) | ||
| 242 | +#define TARGET_NR_fremovexattr (237) | ||
| 243 | +#define TARGET_NR_tkill (238) | ||
| 244 | +#define TARGET_NR_sendfile64 (239) | ||
| 245 | +#define TARGET_NR_futex (240) | ||
| 246 | +#define TARGET_NR_sched_setaffinity (241) | ||
| 247 | +#define TARGET_NR_sched_getaffinity (242) | ||
| 248 | +#define TARGET_NR_io_setup (243) | ||
| 249 | +#define TARGET_NR_io_destroy (244) | ||
| 250 | +#define TARGET_NR_io_getevents (245) | ||
| 251 | +#define TARGET_NR_io_submit (246) | ||
| 252 | +#define TARGET_NR_io_cancel (247) | ||
| 253 | +#define TARGET_NR_exit_group (248) | ||
| 254 | +#define TARGET_NR_lookup_dcookie (249) | ||
| 255 | +#define TARGET_NR_epoll_create (250) | ||
| 256 | +#define TARGET_NR_epoll_ctl (251) | ||
| 257 | +#define TARGET_NR_epoll_wait (252) | ||
| 258 | +#define TARGET_NR_remap_file_pages (253) | ||
| 259 | + /* 254 for set_thread_area */ | ||
| 260 | + /* 255 for get_thread_area */ | ||
| 261 | + /* 256 for set_tid_address */ |
linux-user/i386/syscall.h
0 → 100644
| 1 | +/* default linux values for the selectors */ | ||
| 2 | +#define __USER_CS (0x23) | ||
| 3 | +#define __USER_DS (0x2B) | ||
| 4 | + | ||
| 5 | +struct target_pt_regs { | ||
| 6 | + long ebx; | ||
| 7 | + long ecx; | ||
| 8 | + long edx; | ||
| 9 | + long esi; | ||
| 10 | + long edi; | ||
| 11 | + long ebp; | ||
| 12 | + long eax; | ||
| 13 | + int xds; | ||
| 14 | + int xes; | ||
| 15 | + long orig_eax; | ||
| 16 | + long eip; | ||
| 17 | + int xcs; | ||
| 18 | + long eflags; | ||
| 19 | + long esp; | ||
| 20 | + int xss; | ||
| 21 | +}; | ||
| 22 | + | ||
| 23 | +/* ioctls */ | ||
| 24 | + | ||
| 25 | +#define TARGET_LDT_ENTRIES 8192 | ||
| 26 | +#define TARGET_LDT_ENTRY_SIZE 8 | ||
| 27 | + | ||
| 28 | +#define TARGET_GDT_ENTRY_TLS_ENTRIES 3 | ||
| 29 | +#define TARGET_GDT_ENTRY_TLS_MIN 6 | ||
| 30 | +#define TARGET_GDT_ENTRY_TLS_MAX (TARGET_GDT_ENTRY_TLS_MIN + TARGET_GDT_ENTRY_TLS_ENTRIES - 1) | ||
| 31 | + | ||
| 32 | +struct target_modify_ldt_ldt_s { | ||
| 33 | + unsigned int entry_number; | ||
| 34 | + target_ulong base_addr; | ||
| 35 | + unsigned int limit; | ||
| 36 | + unsigned int flags; | ||
| 37 | +}; | ||
| 38 | + | ||
| 39 | +/* vm86 defines */ | ||
| 40 | + | ||
| 41 | +#define TARGET_BIOSSEG 0x0f000 | ||
| 42 | + | ||
| 43 | +#define TARGET_CPU_086 0 | ||
| 44 | +#define TARGET_CPU_186 1 | ||
| 45 | +#define TARGET_CPU_286 2 | ||
| 46 | +#define TARGET_CPU_386 3 | ||
| 47 | +#define TARGET_CPU_486 4 | ||
| 48 | +#define TARGET_CPU_586 5 | ||
| 49 | + | ||
| 50 | +#define TARGET_VM86_SIGNAL 0 /* return due to signal */ | ||
| 51 | +#define TARGET_VM86_UNKNOWN 1 /* unhandled GP fault - IO-instruction or similar */ | ||
| 52 | +#define TARGET_VM86_INTx 2 /* int3/int x instruction (ARG = x) */ | ||
| 53 | +#define TARGET_VM86_STI 3 /* sti/popf/iret instruction enabled virtual interrupts */ | ||
| 54 | + | ||
| 55 | +/* | ||
| 56 | + * Additional return values when invoking new vm86() | ||
| 57 | + */ | ||
| 58 | +#define TARGET_VM86_PICRETURN 4 /* return due to pending PIC request */ | ||
| 59 | +#define TARGET_VM86_TRAP 6 /* return due to DOS-debugger request */ | ||
| 60 | + | ||
| 61 | +/* | ||
| 62 | + * function codes when invoking new vm86() | ||
| 63 | + */ | ||
| 64 | +#define TARGET_VM86_PLUS_INSTALL_CHECK 0 | ||
| 65 | +#define TARGET_VM86_ENTER 1 | ||
| 66 | +#define TARGET_VM86_ENTER_NO_BYPASS 2 | ||
| 67 | +#define TARGET_VM86_REQUEST_IRQ 3 | ||
| 68 | +#define TARGET_VM86_FREE_IRQ 4 | ||
| 69 | +#define TARGET_VM86_GET_IRQ_BITS 5 | ||
| 70 | +#define TARGET_VM86_GET_AND_RESET_IRQ 6 | ||
| 71 | + | ||
| 72 | +/* | ||
| 73 | + * This is the stack-layout seen by the user space program when we have | ||
| 74 | + * done a translation of "SAVE_ALL" from vm86 mode. The real kernel layout | ||
| 75 | + * is 'kernel_vm86_regs' (see below). | ||
| 76 | + */ | ||
| 77 | + | ||
| 78 | +struct target_vm86_regs { | ||
| 79 | +/* | ||
| 80 | + * normal regs, with special meaning for the segment descriptors.. | ||
| 81 | + */ | ||
| 82 | + target_long ebx; | ||
| 83 | + target_long ecx; | ||
| 84 | + target_long edx; | ||
| 85 | + target_long esi; | ||
| 86 | + target_long edi; | ||
| 87 | + target_long ebp; | ||
| 88 | + target_long eax; | ||
| 89 | + target_long __null_ds; | ||
| 90 | + target_long __null_es; | ||
| 91 | + target_long __null_fs; | ||
| 92 | + target_long __null_gs; | ||
| 93 | + target_long orig_eax; | ||
| 94 | + target_long eip; | ||
| 95 | + unsigned short cs, __csh; | ||
| 96 | + target_long eflags; | ||
| 97 | + target_long esp; | ||
| 98 | + unsigned short ss, __ssh; | ||
| 99 | +/* | ||
| 100 | + * these are specific to v86 mode: | ||
| 101 | + */ | ||
| 102 | + unsigned short es, __esh; | ||
| 103 | + unsigned short ds, __dsh; | ||
| 104 | + unsigned short fs, __fsh; | ||
| 105 | + unsigned short gs, __gsh; | ||
| 106 | +}; | ||
| 107 | + | ||
| 108 | +struct target_revectored_struct { | ||
| 109 | + target_ulong __map[8]; /* 256 bits */ | ||
| 110 | +}; | ||
| 111 | + | ||
| 112 | +struct target_vm86_struct { | ||
| 113 | + struct target_vm86_regs regs; | ||
| 114 | + target_ulong flags; | ||
| 115 | + target_ulong screen_bitmap; | ||
| 116 | + target_ulong cpu_type; | ||
| 117 | + struct target_revectored_struct int_revectored; | ||
| 118 | + struct target_revectored_struct int21_revectored; | ||
| 119 | +}; | ||
| 120 | + | ||
| 121 | +/* | ||
| 122 | + * flags masks | ||
| 123 | + */ | ||
| 124 | +#define TARGET_VM86_SCREEN_BITMAP 0x0001 | ||
| 125 | + | ||
| 126 | +struct target_vm86plus_info_struct { | ||
| 127 | + target_ulong flags; | ||
| 128 | +#define TARGET_force_return_for_pic (1 << 0) | ||
| 129 | +#define TARGET_vm86dbg_active (1 << 1) /* for debugger */ | ||
| 130 | +#define TARGET_vm86dbg_TFpendig (1 << 2) /* for debugger */ | ||
| 131 | +#define TARGET_is_vm86pus (1 << 31) /* for vm86 internal use */ | ||
| 132 | + unsigned char vm86dbg_intxxtab[32]; /* for debugger */ | ||
| 133 | +}; | ||
| 134 | + | ||
| 135 | +struct target_vm86plus_struct { | ||
| 136 | + struct target_vm86_regs regs; | ||
| 137 | + target_ulong flags; | ||
| 138 | + target_ulong screen_bitmap; | ||
| 139 | + target_ulong cpu_type; | ||
| 140 | + struct target_revectored_struct int_revectored; | ||
| 141 | + struct target_revectored_struct int21_revectored; | ||
| 142 | + struct target_vm86plus_info_struct vm86plus; | ||
| 143 | +}; | ||
| 144 | + | ||
| 145 | +/* ipcs */ | ||
| 146 | + | ||
| 147 | +#define TARGET_SEMOP 1 | ||
| 148 | +#define TARGET_SEMGET 2 | ||
| 149 | +#define TARGET_SEMCTL 3 | ||
| 150 | +#define TARGET_MSGSND 11 | ||
| 151 | +#define TARGET_MSGRCV 12 | ||
| 152 | +#define TARGET_MSGGET 13 | ||
| 153 | +#define TARGET_MSGCTL 14 | ||
| 154 | +#define TARGET_SHMAT 21 | ||
| 155 | +#define TARGET_SHMDT 22 | ||
| 156 | +#define TARGET_SHMGET 23 | ||
| 157 | +#define TARGET_SHMCTL 24 | ||
| 158 | + | ||
| 159 | +struct target_msgbuf { | ||
| 160 | + int mtype; | ||
| 161 | + char mtext[1]; | ||
| 162 | +}; | ||
| 163 | + | ||
| 164 | +struct target_ipc_kludge { | ||
| 165 | + unsigned int msgp; /* Really (struct msgbuf *) */ | ||
| 166 | + int msgtyp; | ||
| 167 | +}; | ||
| 168 | + | ||
| 169 | +struct target_ipc_perm { | ||
| 170 | + int key; | ||
| 171 | + unsigned short uid; | ||
| 172 | + unsigned short gid; | ||
| 173 | + unsigned short cuid; | ||
| 174 | + unsigned short cgid; | ||
| 175 | + unsigned short mode; | ||
| 176 | + unsigned short seq; | ||
| 177 | +}; | ||
| 178 | + | ||
| 179 | +struct target_msqid_ds { | ||
| 180 | + struct target_ipc_perm msg_perm; | ||
| 181 | + unsigned int msg_first; /* really struct target_msg* */ | ||
| 182 | + unsigned int msg_last; /* really struct target_msg* */ | ||
| 183 | + unsigned int msg_stime; /* really target_time_t */ | ||
| 184 | + unsigned int msg_rtime; /* really target_time_t */ | ||
| 185 | + unsigned int msg_ctime; /* really target_time_t */ | ||
| 186 | + unsigned int wwait; /* really struct wait_queue* */ | ||
| 187 | + unsigned int rwait; /* really struct wait_queue* */ | ||
| 188 | + unsigned short msg_cbytes; | ||
| 189 | + unsigned short msg_qnum; | ||
| 190 | + unsigned short msg_qbytes; | ||
| 191 | + unsigned short msg_lspid; | ||
| 192 | + unsigned short msg_lrpid; | ||
| 193 | +}; | ||
| 194 | + | ||
| 195 | +struct target_shmid_ds { | ||
| 196 | + struct target_ipc_perm shm_perm; | ||
| 197 | + int shm_segsz; | ||
| 198 | + unsigned int shm_atime; /* really target_time_t */ | ||
| 199 | + unsigned int shm_dtime; /* really target_time_t */ | ||
| 200 | + unsigned int shm_ctime; /* really target_time_t */ | ||
| 201 | + unsigned short shm_cpid; | ||
| 202 | + unsigned short shm_lpid; | ||
| 203 | + short shm_nattch; | ||
| 204 | + unsigned short shm_npages; | ||
| 205 | + unsigned long *shm_pages; | ||
| 206 | + void *attaches; /* really struct shm_desc * */ | ||
| 207 | +}; | ||
| 208 | + | ||
| 209 | +#define TARGET_IPC_RMID 0 | ||
| 210 | +#define TARGET_IPC_SET 1 | ||
| 211 | +#define TARGET_IPC_STAT 2 | ||
| 212 | + | ||
| 213 | +union target_semun { | ||
| 214 | + int val; | ||
| 215 | + unsigned int buf; /* really struct semid_ds * */ | ||
| 216 | + unsigned int array; /* really unsigned short * */ | ||
| 217 | + unsigned int __buf; /* really struct seminfo * */ | ||
| 218 | + unsigned int __pad; /* really void* */ | ||
| 219 | +}; | ||
| 220 | + |
linux-user/i386/syscall_nr.h
0 → 100644
| 1 | +/* | ||
| 2 | + * This file contains the system call numbers. | ||
| 3 | + */ | ||
| 4 | + | ||
| 5 | +#define TARGET_NR_restart_syscall 0 | ||
| 6 | +#define TARGET_NR_exit 1 | ||
| 7 | +#define TARGET_NR_fork 2 | ||
| 8 | +#define TARGET_NR_read 3 | ||
| 9 | +#define TARGET_NR_write 4 | ||
| 10 | +#define TARGET_NR_open 5 | ||
| 11 | +#define TARGET_NR_close 6 | ||
| 12 | +#define TARGET_NR_waitpid 7 | ||
| 13 | +#define TARGET_NR_creat 8 | ||
| 14 | +#define TARGET_NR_link 9 | ||
| 15 | +#define TARGET_NR_unlink 10 | ||
| 16 | +#define TARGET_NR_execve 11 | ||
| 17 | +#define TARGET_NR_chdir 12 | ||
| 18 | +#define TARGET_NR_time 13 | ||
| 19 | +#define TARGET_NR_mknod 14 | ||
| 20 | +#define TARGET_NR_chmod 15 | ||
| 21 | +#define TARGET_NR_lchown 16 | ||
| 22 | +#define TARGET_NR_break 17 | ||
| 23 | +#define TARGET_NR_oldstat 18 | ||
| 24 | +#define TARGET_NR_lseek 19 | ||
| 25 | +#define TARGET_NR_getpid 20 | ||
| 26 | +#define TARGET_NR_mount 21 | ||
| 27 | +#define TARGET_NR_umount 22 | ||
| 28 | +#define TARGET_NR_setuid 23 | ||
| 29 | +#define TARGET_NR_getuid 24 | ||
| 30 | +#define TARGET_NR_stime 25 | ||
| 31 | +#define TARGET_NR_ptrace 26 | ||
| 32 | +#define TARGET_NR_alarm 27 | ||
| 33 | +#define TARGET_NR_oldfstat 28 | ||
| 34 | +#define TARGET_NR_pause 29 | ||
| 35 | +#define TARGET_NR_utime 30 | ||
| 36 | +#define TARGET_NR_stty 31 | ||
| 37 | +#define TARGET_NR_gtty 32 | ||
| 38 | +#define TARGET_NR_access 33 | ||
| 39 | +#define TARGET_NR_nice 34 | ||
| 40 | +#define TARGET_NR_ftime 35 | ||
| 41 | +#define TARGET_NR_sync 36 | ||
| 42 | +#define TARGET_NR_kill 37 | ||
| 43 | +#define TARGET_NR_rename 38 | ||
| 44 | +#define TARGET_NR_mkdir 39 | ||
| 45 | +#define TARGET_NR_rmdir 40 | ||
| 46 | +#define TARGET_NR_dup 41 | ||
| 47 | +#define TARGET_NR_pipe 42 | ||
| 48 | +#define TARGET_NR_times 43 | ||
| 49 | +#define TARGET_NR_prof 44 | ||
| 50 | +#define TARGET_NR_brk 45 | ||
| 51 | +#define TARGET_NR_setgid 46 | ||
| 52 | +#define TARGET_NR_getgid 47 | ||
| 53 | +#define TARGET_NR_signal 48 | ||
| 54 | +#define TARGET_NR_geteuid 49 | ||
| 55 | +#define TARGET_NR_getegid 50 | ||
| 56 | +#define TARGET_NR_acct 51 | ||
| 57 | +#define TARGET_NR_umount2 52 | ||
| 58 | +#define TARGET_NR_lock 53 | ||
| 59 | +#define TARGET_NR_ioctl 54 | ||
| 60 | +#define TARGET_NR_fcntl 55 | ||
| 61 | +#define TARGET_NR_mpx 56 | ||
| 62 | +#define TARGET_NR_setpgid 57 | ||
| 63 | +#define TARGET_NR_ulimit 58 | ||
| 64 | +#define TARGET_NR_oldolduname 59 | ||
| 65 | +#define TARGET_NR_umask 60 | ||
| 66 | +#define TARGET_NR_chroot 61 | ||
| 67 | +#define TARGET_NR_ustat 62 | ||
| 68 | +#define TARGET_NR_dup2 63 | ||
| 69 | +#define TARGET_NR_getppid 64 | ||
| 70 | +#define TARGET_NR_getpgrp 65 | ||
| 71 | +#define TARGET_NR_setsid 66 | ||
| 72 | +#define TARGET_NR_sigaction 67 | ||
| 73 | +#define TARGET_NR_sgetmask 68 | ||
| 74 | +#define TARGET_NR_ssetmask 69 | ||
| 75 | +#define TARGET_NR_setreuid 70 | ||
| 76 | +#define TARGET_NR_setregid 71 | ||
| 77 | +#define TARGET_NR_sigsuspend 72 | ||
| 78 | +#define TARGET_NR_sigpending 73 | ||
| 79 | +#define TARGET_NR_sethostname 74 | ||
| 80 | +#define TARGET_NR_setrlimit 75 | ||
| 81 | +#define TARGET_NR_getrlimit 76 /* Back compatible 2Gig limited rlimit */ | ||
| 82 | +#define TARGET_NR_getrusage 77 | ||
| 83 | +#define TARGET_NR_gettimeofday 78 | ||
| 84 | +#define TARGET_NR_settimeofday 79 | ||
| 85 | +#define TARGET_NR_getgroups 80 | ||
| 86 | +#define TARGET_NR_setgroups 81 | ||
| 87 | +#define TARGET_NR_select 82 | ||
| 88 | +#define TARGET_NR_symlink 83 | ||
| 89 | +#define TARGET_NR_oldlstat 84 | ||
| 90 | +#define TARGET_NR_readlink 85 | ||
| 91 | +#define TARGET_NR_uselib 86 | ||
| 92 | +#define TARGET_NR_swapon 87 | ||
| 93 | +#define TARGET_NR_reboot 88 | ||
| 94 | +#define TARGET_NR_readdir 89 | ||
| 95 | +#define TARGET_NR_mmap 90 | ||
| 96 | +#define TARGET_NR_munmap 91 | ||
| 97 | +#define TARGET_NR_truncate 92 | ||
| 98 | +#define TARGET_NR_ftruncate 93 | ||
| 99 | +#define TARGET_NR_fchmod 94 | ||
| 100 | +#define TARGET_NR_fchown 95 | ||
| 101 | +#define TARGET_NR_getpriority 96 | ||
| 102 | +#define TARGET_NR_setpriority 97 | ||
| 103 | +#define TARGET_NR_profil 98 | ||
| 104 | +#define TARGET_NR_statfs 99 | ||
| 105 | +#define TARGET_NR_fstatfs 100 | ||
| 106 | +#define TARGET_NR_ioperm 101 | ||
| 107 | +#define TARGET_NR_socketcall 102 | ||
| 108 | +#define TARGET_NR_syslog 103 | ||
| 109 | +#define TARGET_NR_setitimer 104 | ||
| 110 | +#define TARGET_NR_getitimer 105 | ||
| 111 | +#define TARGET_NR_stat 106 | ||
| 112 | +#define TARGET_NR_lstat 107 | ||
| 113 | +#define TARGET_NR_fstat 108 | ||
| 114 | +#define TARGET_NR_olduname 109 | ||
| 115 | +#define TARGET_NR_iopl 110 | ||
| 116 | +#define TARGET_NR_vhangup 111 | ||
| 117 | +#define TARGET_NR_idle 112 | ||
| 118 | +#define TARGET_NR_vm86old 113 | ||
| 119 | +#define TARGET_NR_wait4 114 | ||
| 120 | +#define TARGET_NR_swapoff 115 | ||
| 121 | +#define TARGET_NR_sysinfo 116 | ||
| 122 | +#define TARGET_NR_ipc 117 | ||
| 123 | +#define TARGET_NR_fsync 118 | ||
| 124 | +#define TARGET_NR_sigreturn 119 | ||
| 125 | +#define TARGET_NR_clone 120 | ||
| 126 | +#define TARGET_NR_setdomainname 121 | ||
| 127 | +#define TARGET_NR_uname 122 | ||
| 128 | +#define TARGET_NR_modify_ldt 123 | ||
| 129 | +#define TARGET_NR_adjtimex 124 | ||
| 130 | +#define TARGET_NR_mprotect 125 | ||
| 131 | +#define TARGET_NR_sigprocmask 126 | ||
| 132 | +#define TARGET_NR_create_module 127 | ||
| 133 | +#define TARGET_NR_init_module 128 | ||
| 134 | +#define TARGET_NR_delete_module 129 | ||
| 135 | +#define TARGET_NR_get_kernel_syms 130 | ||
| 136 | +#define TARGET_NR_quotactl 131 | ||
| 137 | +#define TARGET_NR_getpgid 132 | ||
| 138 | +#define TARGET_NR_fchdir 133 | ||
| 139 | +#define TARGET_NR_bdflush 134 | ||
| 140 | +#define TARGET_NR_sysfs 135 | ||
| 141 | +#define TARGET_NR_personality 136 | ||
| 142 | +#define TARGET_NR_afs_syscall 137 /* Syscall for Andrew File System */ | ||
| 143 | +#define TARGET_NR_setfsuid 138 | ||
| 144 | +#define TARGET_NR_setfsgid 139 | ||
| 145 | +#define TARGET_NR__llseek 140 | ||
| 146 | +#define TARGET_NR_getdents 141 | ||
| 147 | +#define TARGET_NR__newselect 142 | ||
| 148 | +#define TARGET_NR_flock 143 | ||
| 149 | +#define TARGET_NR_msync 144 | ||
| 150 | +#define TARGET_NR_readv 145 | ||
| 151 | +#define TARGET_NR_writev 146 | ||
| 152 | +#define TARGET_NR_getsid 147 | ||
| 153 | +#define TARGET_NR_fdatasync 148 | ||
| 154 | +#define TARGET_NR__sysctl 149 | ||
| 155 | +#define TARGET_NR_mlock 150 | ||
| 156 | +#define TARGET_NR_munlock 151 | ||
| 157 | +#define TARGET_NR_mlockall 152 | ||
| 158 | +#define TARGET_NR_munlockall 153 | ||
| 159 | +#define TARGET_NR_sched_setparam 154 | ||
| 160 | +#define TARGET_NR_sched_getparam 155 | ||
| 161 | +#define TARGET_NR_sched_setscheduler 156 | ||
| 162 | +#define TARGET_NR_sched_getscheduler 157 | ||
| 163 | +#define TARGET_NR_sched_yield 158 | ||
| 164 | +#define TARGET_NR_sched_get_priority_max 159 | ||
| 165 | +#define TARGET_NR_sched_get_priority_min 160 | ||
| 166 | +#define TARGET_NR_sched_rr_get_interval 161 | ||
| 167 | +#define TARGET_NR_nanosleep 162 | ||
| 168 | +#define TARGET_NR_mremap 163 | ||
| 169 | +#define TARGET_NR_setresuid 164 | ||
| 170 | +#define TARGET_NR_getresuid 165 | ||
| 171 | +#define TARGET_NR_vm86 166 | ||
| 172 | +#define TARGET_NR_query_module 167 | ||
| 173 | +#define TARGET_NR_poll 168 | ||
| 174 | +#define TARGET_NR_nfsservctl 169 | ||
| 175 | +#define TARGET_NR_setresgid 170 | ||
| 176 | +#define TARGET_NR_getresgid 171 | ||
| 177 | +#define TARGET_NR_prctl 172 | ||
| 178 | +#define TARGET_NR_rt_sigreturn 173 | ||
| 179 | +#define TARGET_NR_rt_sigaction 174 | ||
| 180 | +#define TARGET_NR_rt_sigprocmask 175 | ||
| 181 | +#define TARGET_NR_rt_sigpending 176 | ||
| 182 | +#define TARGET_NR_rt_sigtimedwait 177 | ||
| 183 | +#define TARGET_NR_rt_sigqueueinfo 178 | ||
| 184 | +#define TARGET_NR_rt_sigsuspend 179 | ||
| 185 | +#define TARGET_NR_pread 180 | ||
| 186 | +#define TARGET_NR_pwrite 181 | ||
| 187 | +#define TARGET_NR_chown 182 | ||
| 188 | +#define TARGET_NR_getcwd 183 | ||
| 189 | +#define TARGET_NR_capget 184 | ||
| 190 | +#define TARGET_NR_capset 185 | ||
| 191 | +#define TARGET_NR_sigaltstack 186 | ||
| 192 | +#define TARGET_NR_sendfile 187 | ||
| 193 | +#define TARGET_NR_getpmsg 188 /* some people actually want streams */ | ||
| 194 | +#define TARGET_NR_putpmsg 189 /* some people actually want streams */ | ||
| 195 | +#define TARGET_NR_vfork 190 | ||
| 196 | +#define TARGET_NR_ugetrlimit 191 /* SuS compliant getrlimit */ | ||
| 197 | +#define TARGET_NR_mmap2 192 | ||
| 198 | +#define TARGET_NR_truncate64 193 | ||
| 199 | +#define TARGET_NR_ftruncate64 194 | ||
| 200 | +#define TARGET_NR_stat64 195 | ||
| 201 | +#define TARGET_NR_lstat64 196 | ||
| 202 | +#define TARGET_NR_fstat64 197 | ||
| 203 | +#define TARGET_NR_lchown32 198 | ||
| 204 | +#define TARGET_NR_getuid32 199 | ||
| 205 | +#define TARGET_NR_getgid32 200 | ||
| 206 | +#define TARGET_NR_geteuid32 201 | ||
| 207 | +#define TARGET_NR_getegid32 202 | ||
| 208 | +#define TARGET_NR_setreuid32 203 | ||
| 209 | +#define TARGET_NR_setregid32 204 | ||
| 210 | +#define TARGET_NR_getgroups32 205 | ||
| 211 | +#define TARGET_NR_setgroups32 206 | ||
| 212 | +#define TARGET_NR_fchown32 207 | ||
| 213 | +#define TARGET_NR_setresuid32 208 | ||
| 214 | +#define TARGET_NR_getresuid32 209 | ||
| 215 | +#define TARGET_NR_setresgid32 210 | ||
| 216 | +#define TARGET_NR_getresgid32 211 | ||
| 217 | +#define TARGET_NR_chown32 212 | ||
| 218 | +#define TARGET_NR_setuid32 213 | ||
| 219 | +#define TARGET_NR_setgid32 214 | ||
| 220 | +#define TARGET_NR_setfsuid32 215 | ||
| 221 | +#define TARGET_NR_setfsgid32 216 | ||
| 222 | +#define TARGET_NR_pivot_root 217 | ||
| 223 | +#define TARGET_NR_mincore 218 | ||
| 224 | +#define TARGET_NR_madvise 219 | ||
| 225 | +#define TARGET_NR_madvise1 219 /* delete when C lib stub is removed */ | ||
| 226 | +#define TARGET_NR_getdents64 220 | ||
| 227 | +#define TARGET_NR_fcntl64 221 | ||
| 228 | +/* 223 is unused */ | ||
| 229 | +#define TARGET_NR_gettid 224 | ||
| 230 | +#define TARGET_NR_readahead 225 | ||
| 231 | +#define TARGET_NR_setxattr 226 | ||
| 232 | +#define TARGET_NR_lsetxattr 227 | ||
| 233 | +#define TARGET_NR_fsetxattr 228 | ||
| 234 | +#define TARGET_NR_getxattr 229 | ||
| 235 | +#define TARGET_NR_lgetxattr 230 | ||
| 236 | +#define TARGET_NR_fgetxattr 231 | ||
| 237 | +#define TARGET_NR_listxattr 232 | ||
| 238 | +#define TARGET_NR_llistxattr 233 | ||
| 239 | +#define TARGET_NR_flistxattr 234 | ||
| 240 | +#define TARGET_NR_removexattr 235 | ||
| 241 | +#define TARGET_NR_lremovexattr 236 | ||
| 242 | +#define TARGET_NR_fremovexattr 237 | ||
| 243 | +#define TARGET_NR_tkill 238 | ||
| 244 | +#define TARGET_NR_sendfile64 239 | ||
| 245 | +#define TARGET_NR_futex 240 | ||
| 246 | +#define TARGET_NR_sched_setaffinity 241 | ||
| 247 | +#define TARGET_NR_sched_getaffinity 242 | ||
| 248 | +#define TARGET_NR_set_thread_area 243 | ||
| 249 | +#define TARGET_NR_get_thread_area 244 | ||
| 250 | +#define TARGET_NR_io_setup 245 | ||
| 251 | +#define TARGET_NR_io_destroy 246 | ||
| 252 | +#define TARGET_NR_io_getevents 247 | ||
| 253 | +#define TARGET_NR_io_submit 248 | ||
| 254 | +#define TARGET_NR_io_cancel 249 | ||
| 255 | +#define TARGET_NR_fadvise64 250 | ||
| 256 | + | ||
| 257 | +#define TARGET_NR_exit_group 252 | ||
| 258 | +#define TARGET_NR_lookup_dcookie 253 | ||
| 259 | +#define TARGET_NR_epoll_create 254 | ||
| 260 | +#define TARGET_NR_epoll_ctl 255 | ||
| 261 | +#define TARGET_NR_epoll_wait 256 | ||
| 262 | +#define TARGET_NR_remap_file_pages 257 | ||
| 263 | +#define TARGET_NR_set_tid_address 258 | ||
| 264 | +#define TARGET_NR_timer_create 259 | ||
| 265 | +#define TARGET_NR_timer_settime (TARGET_NR_timer_create+1) | ||
| 266 | +#define TARGET_NR_timer_gettime (TARGET_NR_timer_create+2) | ||
| 267 | +#define TARGET_NR_timer_getoverrun (TARGET_NR_timer_create+3) | ||
| 268 | +#define TARGET_NR_timer_delete (TARGET_NR_timer_create+4) | ||
| 269 | +#define TARGET_NR_clock_settime (TARGET_NR_timer_create+5) | ||
| 270 | +#define TARGET_NR_clock_gettime (TARGET_NR_timer_create+6) | ||
| 271 | +#define TARGET_NR_clock_getres (TARGET_NR_timer_create+7) | ||
| 272 | +#define TARGET_NR_clock_nanosleep (TARGET_NR_timer_create+8) | ||
| 273 | + |
target-arm/cpu.h
0 → 100644
| 1 | +/* | ||
| 2 | + * ARM virtual CPU header | ||
| 3 | + * | ||
| 4 | + * Copyright (c) 2003 Fabrice Bellard | ||
| 5 | + * | ||
| 6 | + * This library is free software; you can redistribute it and/or | ||
| 7 | + * modify it under the terms of the GNU Lesser General Public | ||
| 8 | + * License as published by the Free Software Foundation; either | ||
| 9 | + * version 2 of the License, or (at your option) any later version. | ||
| 10 | + * | ||
| 11 | + * This library is distributed in the hope that it will be useful, | ||
| 12 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 14 | + * Lesser General Public License for more details. | ||
| 15 | + * | ||
| 16 | + * You should have received a copy of the GNU Lesser General Public | ||
| 17 | + * License along with this library; if not, write to the Free Software | ||
| 18 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 19 | + */ | ||
| 20 | +#ifndef CPU_ARM_H | ||
| 21 | +#define CPU_ARM_H | ||
| 22 | + | ||
| 23 | +#include "cpu-defs.h" | ||
| 24 | + | ||
| 25 | +#define EXCP_UDEF 1 /* undefined instruction */ | ||
| 26 | +#define EXCP_SWI 2 /* software interrupt */ | ||
| 27 | + | ||
| 28 | +typedef struct CPUARMState { | ||
| 29 | + uint32_t regs[16]; | ||
| 30 | + uint32_t cpsr; | ||
| 31 | + | ||
| 32 | + /* cpsr flag cache for faster execution */ | ||
| 33 | + uint32_t CF; /* 0 or 1 */ | ||
| 34 | + uint32_t VF; /* V is the bit 31. All other bits are undefined */ | ||
| 35 | + uint32_t NZF; /* N is bit 31. Z is computed from NZF */ | ||
| 36 | + | ||
| 37 | + /* exception/interrupt handling */ | ||
| 38 | + jmp_buf jmp_env; | ||
| 39 | + int exception_index; | ||
| 40 | + int interrupt_request; | ||
| 41 | + struct TranslationBlock *current_tb; | ||
| 42 | + int user_mode_only; | ||
| 43 | + | ||
| 44 | + /* user data */ | ||
| 45 | + void *opaque; | ||
| 46 | +} CPUARMState; | ||
| 47 | + | ||
| 48 | +CPUARMState *cpu_arm_init(void); | ||
| 49 | +int cpu_arm_exec(CPUARMState *s); | ||
| 50 | +void cpu_arm_close(CPUARMState *s); | ||
| 51 | +/* you can call this signal handler from your SIGBUS and SIGSEGV | ||
| 52 | + signal handlers to inform the virtual CPU of exceptions. non zero | ||
| 53 | + is returned if the signal was handled by the virtual CPU. */ | ||
| 54 | +struct siginfo; | ||
| 55 | +int cpu_arm_signal_handler(int host_signum, struct siginfo *info, | ||
| 56 | + void *puc); | ||
| 57 | + | ||
| 58 | +void cpu_arm_dump_state(CPUARMState *env, FILE *f, int flags); | ||
| 59 | + | ||
| 60 | +#define TARGET_PAGE_BITS 12 | ||
| 61 | +#include "cpu-all.h" | ||
| 62 | + | ||
| 63 | +#endif |
target-arm/exec.h
0 → 100644
| 1 | +/* | ||
| 2 | + * ARM execution defines | ||
| 3 | + * | ||
| 4 | + * Copyright (c) 2003 Fabrice Bellard | ||
| 5 | + * | ||
| 6 | + * This library is free software; you can redistribute it and/or | ||
| 7 | + * modify it under the terms of the GNU Lesser General Public | ||
| 8 | + * License as published by the Free Software Foundation; either | ||
| 9 | + * version 2 of the License, or (at your option) any later version. | ||
| 10 | + * | ||
| 11 | + * This library is distributed in the hope that it will be useful, | ||
| 12 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 14 | + * Lesser General Public License for more details. | ||
| 15 | + * | ||
| 16 | + * You should have received a copy of the GNU Lesser General Public | ||
| 17 | + * License along with this library; if not, write to the Free Software | ||
| 18 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 19 | + */ | ||
| 20 | +#include "dyngen-exec.h" | ||
| 21 | + | ||
| 22 | +register struct CPUARMState *env asm(AREG0); | ||
| 23 | +register uint32_t T0 asm(AREG1); | ||
| 24 | +register uint32_t T1 asm(AREG2); | ||
| 25 | +register uint32_t T2 asm(AREG3); | ||
| 26 | + | ||
| 27 | +#include "cpu.h" | ||
| 28 | +#include "exec-all.h" | ||
| 29 | + | ||
| 30 | +void cpu_lock(void); | ||
| 31 | +void cpu_unlock(void); | ||
| 32 | +void cpu_loop_exit(void); | ||
| 33 | + | ||
| 34 | +static inline int compute_cpsr(void) | ||
| 35 | +{ | ||
| 36 | + int ZF; | ||
| 37 | + ZF = (env->NZF == 0); | ||
| 38 | + return env->cpsr | (env->NZF & 0x80000000) | (ZF << 30) | | ||
| 39 | + (env->CF << 29) | ((env->VF & 0x80000000) >> 3); | ||
| 40 | +} |
target-arm/op.c
0 → 100644
| 1 | +/* | ||
| 2 | + * ARM micro operations | ||
| 3 | + * | ||
| 4 | + * Copyright (c) 2003 Fabrice Bellard | ||
| 5 | + * | ||
| 6 | + * This library is free software; you can redistribute it and/or | ||
| 7 | + * modify it under the terms of the GNU Lesser General Public | ||
| 8 | + * License as published by the Free Software Foundation; either | ||
| 9 | + * version 2 of the License, or (at your option) any later version. | ||
| 10 | + * | ||
| 11 | + * This library is distributed in the hope that it will be useful, | ||
| 12 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 14 | + * Lesser General Public License for more details. | ||
| 15 | + * | ||
| 16 | + * You should have received a copy of the GNU Lesser General Public | ||
| 17 | + * License along with this library; if not, write to the Free Software | ||
| 18 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 19 | + */ | ||
| 20 | +#include "exec.h" | ||
| 21 | + | ||
| 22 | +#define REGNAME r0 | ||
| 23 | +#define REG (env->regs[0]) | ||
| 24 | +#include "op_template.h" | ||
| 25 | + | ||
| 26 | +#define REGNAME r1 | ||
| 27 | +#define REG (env->regs[1]) | ||
| 28 | +#include "op_template.h" | ||
| 29 | + | ||
| 30 | +#define REGNAME r2 | ||
| 31 | +#define REG (env->regs[2]) | ||
| 32 | +#include "op_template.h" | ||
| 33 | + | ||
| 34 | +#define REGNAME r3 | ||
| 35 | +#define REG (env->regs[3]) | ||
| 36 | +#include "op_template.h" | ||
| 37 | + | ||
| 38 | +#define REGNAME r4 | ||
| 39 | +#define REG (env->regs[4]) | ||
| 40 | +#include "op_template.h" | ||
| 41 | + | ||
| 42 | +#define REGNAME r5 | ||
| 43 | +#define REG (env->regs[5]) | ||
| 44 | +#include "op_template.h" | ||
| 45 | + | ||
| 46 | +#define REGNAME r6 | ||
| 47 | +#define REG (env->regs[6]) | ||
| 48 | +#include "op_template.h" | ||
| 49 | + | ||
| 50 | +#define REGNAME r7 | ||
| 51 | +#define REG (env->regs[7]) | ||
| 52 | +#include "op_template.h" | ||
| 53 | + | ||
| 54 | +#define REGNAME r8 | ||
| 55 | +#define REG (env->regs[8]) | ||
| 56 | +#include "op_template.h" | ||
| 57 | + | ||
| 58 | +#define REGNAME r9 | ||
| 59 | +#define REG (env->regs[9]) | ||
| 60 | +#include "op_template.h" | ||
| 61 | + | ||
| 62 | +#define REGNAME r10 | ||
| 63 | +#define REG (env->regs[10]) | ||
| 64 | +#include "op_template.h" | ||
| 65 | + | ||
| 66 | +#define REGNAME r11 | ||
| 67 | +#define REG (env->regs[11]) | ||
| 68 | +#include "op_template.h" | ||
| 69 | + | ||
| 70 | +#define REGNAME r12 | ||
| 71 | +#define REG (env->regs[12]) | ||
| 72 | +#include "op_template.h" | ||
| 73 | + | ||
| 74 | +#define REGNAME r13 | ||
| 75 | +#define REG (env->regs[13]) | ||
| 76 | +#include "op_template.h" | ||
| 77 | + | ||
| 78 | +#define REGNAME r14 | ||
| 79 | +#define REG (env->regs[14]) | ||
| 80 | +#include "op_template.h" | ||
| 81 | + | ||
| 82 | +#define REGNAME r15 | ||
| 83 | +#define REG (env->regs[15]) | ||
| 84 | +#include "op_template.h" | ||
| 85 | + | ||
| 86 | +void OPPROTO op_movl_T0_0(void) | ||
| 87 | +{ | ||
| 88 | + T0 = 0; | ||
| 89 | +} | ||
| 90 | + | ||
| 91 | +void OPPROTO op_movl_T0_im(void) | ||
| 92 | +{ | ||
| 93 | + T0 = PARAM1; | ||
| 94 | +} | ||
| 95 | + | ||
| 96 | +void OPPROTO op_movl_T1_im(void) | ||
| 97 | +{ | ||
| 98 | + T1 = PARAM1; | ||
| 99 | +} | ||
| 100 | + | ||
| 101 | +void OPPROTO op_movl_T2_im(void) | ||
| 102 | +{ | ||
| 103 | + T2 = PARAM1; | ||
| 104 | +} | ||
| 105 | + | ||
| 106 | +void OPPROTO op_addl_T1_im(void) | ||
| 107 | +{ | ||
| 108 | + T1 += PARAM1; | ||
| 109 | +} | ||
| 110 | + | ||
| 111 | +void OPPROTO op_addl_T1_T2(void) | ||
| 112 | +{ | ||
| 113 | + T1 += T2; | ||
| 114 | +} | ||
| 115 | + | ||
| 116 | +void OPPROTO op_subl_T1_T2(void) | ||
| 117 | +{ | ||
| 118 | + T1 -= T2; | ||
| 119 | +} | ||
| 120 | + | ||
| 121 | +void OPPROTO op_addl_T0_T1(void) | ||
| 122 | +{ | ||
| 123 | + T0 += T1; | ||
| 124 | +} | ||
| 125 | + | ||
| 126 | +void OPPROTO op_addl_T0_T1_cc(void) | ||
| 127 | +{ | ||
| 128 | + unsigned int src1; | ||
| 129 | + src1 = T0; | ||
| 130 | + T0 += T1; | ||
| 131 | + env->NZF = T0; | ||
| 132 | + env->CF = T0 < src1; | ||
| 133 | + env->VF = (src1 ^ T1 ^ -1) & (src1 ^ T0); | ||
| 134 | +} | ||
| 135 | + | ||
| 136 | +void OPPROTO op_adcl_T0_T1(void) | ||
| 137 | +{ | ||
| 138 | + T0 += T1 + env->CF; | ||
| 139 | +} | ||
| 140 | + | ||
| 141 | +void OPPROTO op_adcl_T0_T1_cc(void) | ||
| 142 | +{ | ||
| 143 | + unsigned int src1; | ||
| 144 | + src1 = T0; | ||
| 145 | + if (!env->CF) { | ||
| 146 | + T0 += T1; | ||
| 147 | + env->CF = T0 < src1; | ||
| 148 | + } else { | ||
| 149 | + T0 += T1 + 1; | ||
| 150 | + env->CF = T0 <= src1; | ||
| 151 | + } | ||
| 152 | + env->VF = (src1 ^ T1 ^ -1) & (src1 ^ T0); | ||
| 153 | + env->NZF = T0; | ||
| 154 | + FORCE_RET(); | ||
| 155 | +} | ||
| 156 | + | ||
| 157 | +#define OPSUB(sub, sbc, res, T0, T1) \ | ||
| 158 | + \ | ||
| 159 | +void OPPROTO op_ ## sub ## l_T0_T1(void) \ | ||
| 160 | +{ \ | ||
| 161 | + res = T0 - T1; \ | ||
| 162 | +} \ | ||
| 163 | + \ | ||
| 164 | +void OPPROTO op_ ## sub ## l_T0_T1_cc(void) \ | ||
| 165 | +{ \ | ||
| 166 | + unsigned int src1; \ | ||
| 167 | + src1 = T0; \ | ||
| 168 | + T0 -= T1; \ | ||
| 169 | + env->NZF = T0; \ | ||
| 170 | + env->CF = src1 >= T1; \ | ||
| 171 | + env->VF = (src1 ^ T1) & (src1 ^ T0); \ | ||
| 172 | + res = T0; \ | ||
| 173 | +} \ | ||
| 174 | + \ | ||
| 175 | +void OPPROTO op_ ## sbc ## l_T0_T1(void) \ | ||
| 176 | +{ \ | ||
| 177 | + res = T0 - T1 + env->CF - 1; \ | ||
| 178 | +} \ | ||
| 179 | + \ | ||
| 180 | +void OPPROTO op_ ## sbc ## l_T0_T1_cc(void) \ | ||
| 181 | +{ \ | ||
| 182 | + unsigned int src1; \ | ||
| 183 | + src1 = T0; \ | ||
| 184 | + if (!env->CF) { \ | ||
| 185 | + T0 = T0 - T1 - 1; \ | ||
| 186 | + env->CF = src1 >= T1; \ | ||
| 187 | + } else { \ | ||
| 188 | + T0 = T0 - T1; \ | ||
| 189 | + env->CF = src1 > T1; \ | ||
| 190 | + } \ | ||
| 191 | + env->VF = (src1 ^ T1) & (src1 ^ T0); \ | ||
| 192 | + env->NZF = T0; \ | ||
| 193 | + res = T0; \ | ||
| 194 | + FORCE_RET(); \ | ||
| 195 | +} | ||
| 196 | + | ||
| 197 | +OPSUB(sub, sbc, T0, T0, T1) | ||
| 198 | + | ||
| 199 | +OPSUB(rsb, rsc, T0, T1, T0) | ||
| 200 | + | ||
| 201 | +void OPPROTO op_andl_T0_T1(void) | ||
| 202 | +{ | ||
| 203 | + T0 &= T1; | ||
| 204 | +} | ||
| 205 | + | ||
| 206 | +void OPPROTO op_xorl_T0_T1(void) | ||
| 207 | +{ | ||
| 208 | + T0 ^= T1; | ||
| 209 | +} | ||
| 210 | + | ||
| 211 | +void OPPROTO op_orl_T0_T1(void) | ||
| 212 | +{ | ||
| 213 | + T0 |= T1; | ||
| 214 | +} | ||
| 215 | + | ||
| 216 | +void OPPROTO op_bicl_T0_T1(void) | ||
| 217 | +{ | ||
| 218 | + T0 &= ~T1; | ||
| 219 | +} | ||
| 220 | + | ||
| 221 | +void OPPROTO op_notl_T1(void) | ||
| 222 | +{ | ||
| 223 | + T1 = ~T1; | ||
| 224 | +} | ||
| 225 | + | ||
| 226 | +void OPPROTO op_logic_T0_cc(void) | ||
| 227 | +{ | ||
| 228 | + env->NZF = T0; | ||
| 229 | +} | ||
| 230 | + | ||
| 231 | +void OPPROTO op_logic_T1_cc(void) | ||
| 232 | +{ | ||
| 233 | + env->NZF = T1; | ||
| 234 | +} | ||
| 235 | + | ||
| 236 | +#define EIP (env->regs[15]) | ||
| 237 | + | ||
| 238 | +void OPPROTO op_test_eq(void) | ||
| 239 | +{ | ||
| 240 | + if (env->NZF == 0) | ||
| 241 | + JUMP_TB(op_test_eq, PARAM1, 0, PARAM2); | ||
| 242 | + FORCE_RET(); | ||
| 243 | +} | ||
| 244 | + | ||
| 245 | +void OPPROTO op_test_ne(void) | ||
| 246 | +{ | ||
| 247 | + if (env->NZF != 0) | ||
| 248 | + JUMP_TB(op_test_ne, PARAM1, 0, PARAM2); | ||
| 249 | + FORCE_RET(); | ||
| 250 | +} | ||
| 251 | + | ||
| 252 | +void OPPROTO op_test_cs(void) | ||
| 253 | +{ | ||
| 254 | + if (env->CF != 0) | ||
| 255 | + JUMP_TB(op_test_cs, PARAM1, 0, PARAM2); | ||
| 256 | + FORCE_RET(); | ||
| 257 | +} | ||
| 258 | + | ||
| 259 | +void OPPROTO op_test_cc(void) | ||
| 260 | +{ | ||
| 261 | + if (env->CF == 0) | ||
| 262 | + JUMP_TB(op_test_cc, PARAM1, 0, PARAM2); | ||
| 263 | + FORCE_RET(); | ||
| 264 | +} | ||
| 265 | + | ||
| 266 | +void OPPROTO op_test_mi(void) | ||
| 267 | +{ | ||
| 268 | + if ((env->NZF & 0x80000000) != 0) | ||
| 269 | + JUMP_TB(op_test_mi, PARAM1, 0, PARAM2); | ||
| 270 | + FORCE_RET(); | ||
| 271 | +} | ||
| 272 | + | ||
| 273 | +void OPPROTO op_test_pl(void) | ||
| 274 | +{ | ||
| 275 | + if ((env->NZF & 0x80000000) == 0) | ||
| 276 | + JUMP_TB(op_test_pl, PARAM1, 0, PARAM2); | ||
| 277 | + FORCE_RET(); | ||
| 278 | +} | ||
| 279 | + | ||
| 280 | +void OPPROTO op_test_vs(void) | ||
| 281 | +{ | ||
| 282 | + if ((env->VF & 0x80000000) != 0) | ||
| 283 | + JUMP_TB(op_test_vs, PARAM1, 0, PARAM2); | ||
| 284 | + FORCE_RET(); | ||
| 285 | +} | ||
| 286 | + | ||
| 287 | +void OPPROTO op_test_vc(void) | ||
| 288 | +{ | ||
| 289 | + if ((env->VF & 0x80000000) == 0) | ||
| 290 | + JUMP_TB(op_test_vc, PARAM1, 0, PARAM2); | ||
| 291 | + FORCE_RET(); | ||
| 292 | +} | ||
| 293 | + | ||
| 294 | +void OPPROTO op_test_hi(void) | ||
| 295 | +{ | ||
| 296 | + if (env->CF != 0 && env->NZF != 0) | ||
| 297 | + JUMP_TB(op_test_hi, PARAM1, 0, PARAM2); | ||
| 298 | + FORCE_RET(); | ||
| 299 | +} | ||
| 300 | + | ||
| 301 | +void OPPROTO op_test_ls(void) | ||
| 302 | +{ | ||
| 303 | + if (env->CF == 0 || env->NZF == 0) | ||
| 304 | + JUMP_TB(op_test_ls, PARAM1, 0, PARAM2); | ||
| 305 | + FORCE_RET(); | ||
| 306 | +} | ||
| 307 | + | ||
| 308 | +void OPPROTO op_test_ge(void) | ||
| 309 | +{ | ||
| 310 | + if (((env->VF ^ env->NZF) & 0x80000000) == 0) | ||
| 311 | + JUMP_TB(op_test_ge, PARAM1, 0, PARAM2); | ||
| 312 | + FORCE_RET(); | ||
| 313 | +} | ||
| 314 | + | ||
| 315 | +void OPPROTO op_test_lt(void) | ||
| 316 | +{ | ||
| 317 | + if (((env->VF ^ env->NZF) & 0x80000000) != 0) | ||
| 318 | + JUMP_TB(op_test_lt, PARAM1, 0, PARAM2); | ||
| 319 | + FORCE_RET(); | ||
| 320 | +} | ||
| 321 | + | ||
| 322 | +void OPPROTO op_test_gt(void) | ||
| 323 | +{ | ||
| 324 | + if (env->NZF != 0 && ((env->VF ^ env->NZF) & 0x80000000) == 0) | ||
| 325 | + JUMP_TB(op_test_gt, PARAM1, 0, PARAM2); | ||
| 326 | + FORCE_RET(); | ||
| 327 | +} | ||
| 328 | + | ||
| 329 | +void OPPROTO op_test_le(void) | ||
| 330 | +{ | ||
| 331 | + if (env->NZF == 0 || ((env->VF ^ env->NZF) & 0x80000000) != 0) | ||
| 332 | + JUMP_TB(op_test_le, PARAM1, 0, PARAM2); | ||
| 333 | + FORCE_RET(); | ||
| 334 | +} | ||
| 335 | + | ||
| 336 | +void OPPROTO op_jmp(void) | ||
| 337 | +{ | ||
| 338 | + JUMP_TB(op_jmp, PARAM1, 1, PARAM2); | ||
| 339 | +} | ||
| 340 | + | ||
| 341 | +void OPPROTO op_exit_tb(void) | ||
| 342 | +{ | ||
| 343 | + EXIT_TB(); | ||
| 344 | +} | ||
| 345 | + | ||
| 346 | +void OPPROTO op_movl_T0_psr(void) | ||
| 347 | +{ | ||
| 348 | + T0 = compute_cpsr(); | ||
| 349 | +} | ||
| 350 | + | ||
| 351 | +/* NOTE: N = 1 and Z = 1 cannot be stored currently */ | ||
| 352 | +void OPPROTO op_movl_psr_T0(void) | ||
| 353 | +{ | ||
| 354 | + unsigned int psr; | ||
| 355 | + psr = T0; | ||
| 356 | + env->CF = (psr >> 29) & 1; | ||
| 357 | + env->NZF = (psr & 0xc0000000) ^ 0x40000000; | ||
| 358 | + env->VF = (psr << 3) & 0x80000000; | ||
| 359 | + /* for user mode we do not update other state info */ | ||
| 360 | +} | ||
| 361 | + | ||
| 362 | +void OPPROTO op_mul_T0_T1(void) | ||
| 363 | +{ | ||
| 364 | + T0 = T0 * T1; | ||
| 365 | +} | ||
| 366 | + | ||
| 367 | +/* 64 bit unsigned mul */ | ||
| 368 | +void OPPROTO op_mull_T0_T1(void) | ||
| 369 | +{ | ||
| 370 | + uint64_t res; | ||
| 371 | + res = T0 * T1; | ||
| 372 | + T1 = res >> 32; | ||
| 373 | + T0 = res; | ||
| 374 | +} | ||
| 375 | + | ||
| 376 | +/* 64 bit signed mul */ | ||
| 377 | +void OPPROTO op_imull_T0_T1(void) | ||
| 378 | +{ | ||
| 379 | + uint64_t res; | ||
| 380 | + res = (int32_t)T0 * (int32_t)T1; | ||
| 381 | + T1 = res >> 32; | ||
| 382 | + T0 = res; | ||
| 383 | +} | ||
| 384 | + | ||
| 385 | +void OPPROTO op_addq_T0_T1(void) | ||
| 386 | +{ | ||
| 387 | + uint64_t res; | ||
| 388 | + res = ((uint64_t)T1 << 32) | T0; | ||
| 389 | + res += ((uint64_t)(env->regs[PARAM2]) << 32) | (env->regs[PARAM1]); | ||
| 390 | + T1 = res >> 32; | ||
| 391 | + T0 = res; | ||
| 392 | +} | ||
| 393 | + | ||
| 394 | +void OPPROTO op_logicq_cc(void) | ||
| 395 | +{ | ||
| 396 | + env->NZF = (T1 & 0x80000000) | ((T0 | T1) != 0); | ||
| 397 | +} | ||
| 398 | + | ||
| 399 | +/* memory access */ | ||
| 400 | + | ||
| 401 | +void OPPROTO op_ldub_T0_T1(void) | ||
| 402 | +{ | ||
| 403 | + T0 = ldub((void *)T1); | ||
| 404 | +} | ||
| 405 | + | ||
| 406 | +void OPPROTO op_ldsb_T0_T1(void) | ||
| 407 | +{ | ||
| 408 | + T0 = ldsb((void *)T1); | ||
| 409 | +} | ||
| 410 | + | ||
| 411 | +void OPPROTO op_lduw_T0_T1(void) | ||
| 412 | +{ | ||
| 413 | + T0 = lduw((void *)T1); | ||
| 414 | +} | ||
| 415 | + | ||
| 416 | +void OPPROTO op_ldsw_T0_T1(void) | ||
| 417 | +{ | ||
| 418 | + T0 = ldsw((void *)T1); | ||
| 419 | +} | ||
| 420 | + | ||
| 421 | +void OPPROTO op_ldl_T0_T1(void) | ||
| 422 | +{ | ||
| 423 | + T0 = ldl((void *)T1); | ||
| 424 | +} | ||
| 425 | + | ||
| 426 | +void OPPROTO op_stb_T0_T1(void) | ||
| 427 | +{ | ||
| 428 | + stb((void *)T1, T0); | ||
| 429 | +} | ||
| 430 | + | ||
| 431 | +void OPPROTO op_stw_T0_T1(void) | ||
| 432 | +{ | ||
| 433 | + stw((void *)T1, T0); | ||
| 434 | +} | ||
| 435 | + | ||
| 436 | +void OPPROTO op_stl_T0_T1(void) | ||
| 437 | +{ | ||
| 438 | + stl((void *)T1, T0); | ||
| 439 | +} | ||
| 440 | + | ||
| 441 | +void OPPROTO op_swpb_T0_T1(void) | ||
| 442 | +{ | ||
| 443 | + int tmp; | ||
| 444 | + | ||
| 445 | + cpu_lock(); | ||
| 446 | + tmp = ldub((void *)T1); | ||
| 447 | + stb((void *)T1, T0); | ||
| 448 | + T0 = tmp; | ||
| 449 | + cpu_unlock(); | ||
| 450 | +} | ||
| 451 | + | ||
| 452 | +void OPPROTO op_swpl_T0_T1(void) | ||
| 453 | +{ | ||
| 454 | + int tmp; | ||
| 455 | + | ||
| 456 | + cpu_lock(); | ||
| 457 | + tmp = ldl((void *)T1); | ||
| 458 | + stl((void *)T1, T0); | ||
| 459 | + T0 = tmp; | ||
| 460 | + cpu_unlock(); | ||
| 461 | +} | ||
| 462 | + | ||
| 463 | +/* shifts */ | ||
| 464 | + | ||
| 465 | +/* T1 based */ | ||
| 466 | +void OPPROTO op_shll_T1_im(void) | ||
| 467 | +{ | ||
| 468 | + T1 = T1 << PARAM1; | ||
| 469 | +} | ||
| 470 | + | ||
| 471 | +void OPPROTO op_shrl_T1_im(void) | ||
| 472 | +{ | ||
| 473 | + T1 = (uint32_t)T1 >> PARAM1; | ||
| 474 | +} | ||
| 475 | + | ||
| 476 | +void OPPROTO op_sarl_T1_im(void) | ||
| 477 | +{ | ||
| 478 | + T1 = (int32_t)T1 >> PARAM1; | ||
| 479 | +} | ||
| 480 | + | ||
| 481 | +void OPPROTO op_rorl_T1_im(void) | ||
| 482 | +{ | ||
| 483 | + int shift; | ||
| 484 | + shift = PARAM1; | ||
| 485 | + T1 = ((uint32_t)T1 >> shift) | (T1 << (32 - shift)); | ||
| 486 | +} | ||
| 487 | + | ||
| 488 | +/* T1 based, set C flag */ | ||
| 489 | +void OPPROTO op_shll_T1_im_cc(void) | ||
| 490 | +{ | ||
| 491 | + env->CF = (T1 >> (32 - PARAM1)) & 1; | ||
| 492 | + T1 = T1 << PARAM1; | ||
| 493 | +} | ||
| 494 | + | ||
| 495 | +void OPPROTO op_shrl_T1_im_cc(void) | ||
| 496 | +{ | ||
| 497 | + env->CF = (T1 >> (PARAM1 - 1)) & 1; | ||
| 498 | + T1 = (uint32_t)T1 >> PARAM1; | ||
| 499 | +} | ||
| 500 | + | ||
| 501 | +void OPPROTO op_sarl_T1_im_cc(void) | ||
| 502 | +{ | ||
| 503 | + env->CF = (T1 >> (PARAM1 - 1)) & 1; | ||
| 504 | + T1 = (int32_t)T1 >> PARAM1; | ||
| 505 | +} | ||
| 506 | + | ||
| 507 | +void OPPROTO op_rorl_T1_im_cc(void) | ||
| 508 | +{ | ||
| 509 | + int shift; | ||
| 510 | + shift = PARAM1; | ||
| 511 | + env->CF = (T1 >> (shift - 1)) & 1; | ||
| 512 | + T1 = ((uint32_t)T1 >> shift) | (T1 << (32 - shift)); | ||
| 513 | +} | ||
| 514 | + | ||
| 515 | +/* T2 based */ | ||
| 516 | +void OPPROTO op_shll_T2_im(void) | ||
| 517 | +{ | ||
| 518 | + T2 = T2 << PARAM1; | ||
| 519 | +} | ||
| 520 | + | ||
| 521 | +void OPPROTO op_shrl_T2_im(void) | ||
| 522 | +{ | ||
| 523 | + T2 = (uint32_t)T2 >> PARAM1; | ||
| 524 | +} | ||
| 525 | + | ||
| 526 | +void OPPROTO op_sarl_T2_im(void) | ||
| 527 | +{ | ||
| 528 | + T2 = (int32_t)T2 >> PARAM1; | ||
| 529 | +} | ||
| 530 | + | ||
| 531 | +void OPPROTO op_rorl_T2_im(void) | ||
| 532 | +{ | ||
| 533 | + int shift; | ||
| 534 | + shift = PARAM1; | ||
| 535 | + T2 = ((uint32_t)T2 >> shift) | (T2 << (32 - shift)); | ||
| 536 | +} | ||
| 537 | + | ||
| 538 | +/* T1 based, use T0 as shift count */ | ||
| 539 | + | ||
| 540 | +void OPPROTO op_shll_T1_T0(void) | ||
| 541 | +{ | ||
| 542 | + int shift; | ||
| 543 | + shift = T0 & 0xff; | ||
| 544 | + if (shift >= 32) | ||
| 545 | + T1 = 0; | ||
| 546 | + else | ||
| 547 | + T1 = T1 << shift; | ||
| 548 | + FORCE_RET(); | ||
| 549 | +} | ||
| 550 | + | ||
| 551 | +void OPPROTO op_shrl_T1_T0(void) | ||
| 552 | +{ | ||
| 553 | + int shift; | ||
| 554 | + shift = T0 & 0xff; | ||
| 555 | + if (shift >= 32) | ||
| 556 | + T1 = 0; | ||
| 557 | + else | ||
| 558 | + T1 = (uint32_t)T1 >> shift; | ||
| 559 | + FORCE_RET(); | ||
| 560 | +} | ||
| 561 | + | ||
| 562 | +void OPPROTO op_sarl_T1_T0(void) | ||
| 563 | +{ | ||
| 564 | + int shift; | ||
| 565 | + shift = T0 & 0xff; | ||
| 566 | + if (shift >= 32) | ||
| 567 | + shift = 31; | ||
| 568 | + T1 = (int32_t)T1 >> shift; | ||
| 569 | +} | ||
| 570 | + | ||
| 571 | +void OPPROTO op_rorl_T1_T0(void) | ||
| 572 | +{ | ||
| 573 | + int shift; | ||
| 574 | + shift = T0 & 0x1f; | ||
| 575 | + if (shift) { | ||
| 576 | + T1 = ((uint32_t)T1 >> shift) | (T1 << (32 - shift)); | ||
| 577 | + } | ||
| 578 | + FORCE_RET(); | ||
| 579 | +} | ||
| 580 | + | ||
| 581 | +/* T1 based, use T0 as shift count and compute CF */ | ||
| 582 | + | ||
| 583 | +void OPPROTO op_shll_T1_T0_cc(void) | ||
| 584 | +{ | ||
| 585 | + int shift; | ||
| 586 | + shift = T0 & 0xff; | ||
| 587 | + if (shift >= 32) { | ||
| 588 | + if (shift == 32) | ||
| 589 | + env->CF = T1 & 1; | ||
| 590 | + else | ||
| 591 | + env->CF = 0; | ||
| 592 | + T1 = 0; | ||
| 593 | + } else if (shift != 0) { | ||
| 594 | + env->CF = (T1 >> (32 - shift)) & 1; | ||
| 595 | + T1 = T1 << shift; | ||
| 596 | + } | ||
| 597 | + FORCE_RET(); | ||
| 598 | +} | ||
| 599 | + | ||
| 600 | +void OPPROTO op_shrl_T1_T0_cc(void) | ||
| 601 | +{ | ||
| 602 | + int shift; | ||
| 603 | + shift = T0 & 0xff; | ||
| 604 | + if (shift >= 32) { | ||
| 605 | + if (shift == 32) | ||
| 606 | + env->CF = (T1 >> 31) & 1; | ||
| 607 | + else | ||
| 608 | + env->CF = 0; | ||
| 609 | + T1 = 0; | ||
| 610 | + } else if (shift != 0) { | ||
| 611 | + env->CF = (T1 >> (shift - 1)) & 1; | ||
| 612 | + T1 = (uint32_t)T1 >> shift; | ||
| 613 | + } | ||
| 614 | + FORCE_RET(); | ||
| 615 | +} | ||
| 616 | + | ||
| 617 | +void OPPROTO op_sarl_T1_T0_cc(void) | ||
| 618 | +{ | ||
| 619 | + int shift; | ||
| 620 | + shift = T0 & 0xff; | ||
| 621 | + if (shift >= 32) { | ||
| 622 | + env->CF = (T1 >> 31) & 1; | ||
| 623 | + T1 = (int32_t)T1 >> 31; | ||
| 624 | + } else { | ||
| 625 | + env->CF = (T1 >> (shift - 1)) & 1; | ||
| 626 | + T1 = (int32_t)T1 >> shift; | ||
| 627 | + } | ||
| 628 | + FORCE_RET(); | ||
| 629 | +} | ||
| 630 | + | ||
| 631 | +void OPPROTO op_rorl_T1_T0_cc(void) | ||
| 632 | +{ | ||
| 633 | + int shift1, shift; | ||
| 634 | + shift1 = T0 & 0xff; | ||
| 635 | + shift = shift1 & 0x1f; | ||
| 636 | + if (shift == 0) { | ||
| 637 | + if (shift1 != 0) | ||
| 638 | + env->CF = (T1 >> 31) & 1; | ||
| 639 | + } else { | ||
| 640 | + env->CF = (T1 >> (shift - 1)) & 1; | ||
| 641 | + T1 = ((uint32_t)T1 >> shift) | (T1 << (32 - shift)); | ||
| 642 | + } | ||
| 643 | + FORCE_RET(); | ||
| 644 | +} | ||
| 645 | + | ||
| 646 | +/* exceptions */ | ||
| 647 | + | ||
| 648 | +void OPPROTO op_swi(void) | ||
| 649 | +{ | ||
| 650 | + env->exception_index = EXCP_SWI; | ||
| 651 | + cpu_loop_exit(); | ||
| 652 | +} | ||
| 653 | + | ||
| 654 | +void OPPROTO op_undef_insn(void) | ||
| 655 | +{ | ||
| 656 | + env->exception_index = EXCP_UDEF; | ||
| 657 | + cpu_loop_exit(); | ||
| 658 | +} | ||
| 659 | + | ||
| 660 | +/* thread support */ | ||
| 661 | + | ||
| 662 | +spinlock_t global_cpu_lock = SPIN_LOCK_UNLOCKED; | ||
| 663 | + | ||
| 664 | +void cpu_lock(void) | ||
| 665 | +{ | ||
| 666 | + spin_lock(&global_cpu_lock); | ||
| 667 | +} | ||
| 668 | + | ||
| 669 | +void cpu_unlock(void) | ||
| 670 | +{ | ||
| 671 | + spin_unlock(&global_cpu_lock); | ||
| 672 | +} | ||
| 673 | + |
target-arm/op_template.h
0 → 100644
| 1 | +/* | ||
| 2 | + * ARM micro operations (templates for various register related | ||
| 3 | + * operations) | ||
| 4 | + * | ||
| 5 | + * Copyright (c) 2003 Fabrice Bellard | ||
| 6 | + * | ||
| 7 | + * This library is free software; you can redistribute it and/or | ||
| 8 | + * modify it under the terms of the GNU Lesser General Public | ||
| 9 | + * License as published by the Free Software Foundation; either | ||
| 10 | + * version 2 of the License, or (at your option) any later version. | ||
| 11 | + * | ||
| 12 | + * This library is distributed in the hope that it will be useful, | ||
| 13 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 15 | + * Lesser General Public License for more details. | ||
| 16 | + * | ||
| 17 | + * You should have received a copy of the GNU Lesser General Public | ||
| 18 | + * License along with this library; if not, write to the Free Software | ||
| 19 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 20 | + */ | ||
| 21 | + | ||
| 22 | +void OPPROTO glue(op_movl_T0_, REGNAME)(void) | ||
| 23 | +{ | ||
| 24 | + T0 = REG; | ||
| 25 | +} | ||
| 26 | + | ||
| 27 | +void OPPROTO glue(op_movl_T1_, REGNAME)(void) | ||
| 28 | +{ | ||
| 29 | + T1 = REG; | ||
| 30 | +} | ||
| 31 | + | ||
| 32 | +void OPPROTO glue(op_movl_T2_, REGNAME)(void) | ||
| 33 | +{ | ||
| 34 | + T2 = REG; | ||
| 35 | +} | ||
| 36 | + | ||
| 37 | +void OPPROTO glue(glue(op_movl_, REGNAME), _T0)(void) | ||
| 38 | +{ | ||
| 39 | + REG = T0; | ||
| 40 | +} | ||
| 41 | + | ||
| 42 | +void OPPROTO glue(glue(op_movl_, REGNAME), _T1)(void) | ||
| 43 | +{ | ||
| 44 | + REG = T1; | ||
| 45 | +} | ||
| 46 | + | ||
| 47 | +#undef REG | ||
| 48 | +#undef REGNAME |
target-arm/translate.c
0 → 100644
| 1 | +/* | ||
| 2 | + * ARM translation | ||
| 3 | + * | ||
| 4 | + * Copyright (c) 2003 Fabrice Bellard | ||
| 5 | + * | ||
| 6 | + * This library is free software; you can redistribute it and/or | ||
| 7 | + * modify it under the terms of the GNU Lesser General Public | ||
| 8 | + * License as published by the Free Software Foundation; either | ||
| 9 | + * version 2 of the License, or (at your option) any later version. | ||
| 10 | + * | ||
| 11 | + * This library is distributed in the hope that it will be useful, | ||
| 12 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 14 | + * Lesser General Public License for more details. | ||
| 15 | + * | ||
| 16 | + * You should have received a copy of the GNU Lesser General Public | ||
| 17 | + * License along with this library; if not, write to the Free Software | ||
| 18 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 19 | + */ | ||
| 20 | +#include <stdarg.h> | ||
| 21 | +#include <stdlib.h> | ||
| 22 | +#include <stdio.h> | ||
| 23 | +#include <string.h> | ||
| 24 | +#include <inttypes.h> | ||
| 25 | + | ||
| 26 | +#include "cpu.h" | ||
| 27 | +#include "exec-all.h" | ||
| 28 | +#include "disas.h" | ||
| 29 | + | ||
| 30 | +/* internal defines */ | ||
| 31 | +typedef struct DisasContext { | ||
| 32 | + uint8_t *pc; | ||
| 33 | + int is_jmp; | ||
| 34 | + struct TranslationBlock *tb; | ||
| 35 | +} DisasContext; | ||
| 36 | + | ||
| 37 | +#define DISAS_JUMP_NEXT 4 | ||
| 38 | + | ||
| 39 | +/* XXX: move that elsewhere */ | ||
| 40 | +static uint16_t *gen_opc_ptr; | ||
| 41 | +static uint32_t *gen_opparam_ptr; | ||
| 42 | +extern FILE *logfile; | ||
| 43 | +extern int loglevel; | ||
| 44 | + | ||
| 45 | +enum { | ||
| 46 | +#define DEF(s, n, copy_size) INDEX_op_ ## s, | ||
| 47 | +#include "opc.h" | ||
| 48 | +#undef DEF | ||
| 49 | + NB_OPS, | ||
| 50 | +}; | ||
| 51 | + | ||
| 52 | +#include "gen-op.h" | ||
| 53 | + | ||
| 54 | +typedef void (GenOpFunc)(void); | ||
| 55 | +typedef void (GenOpFunc1)(long); | ||
| 56 | +typedef void (GenOpFunc2)(long, long); | ||
| 57 | +typedef void (GenOpFunc3)(long, long, long); | ||
| 58 | + | ||
| 59 | +static GenOpFunc2 *gen_test_cc[14] = { | ||
| 60 | + gen_op_test_eq, | ||
| 61 | + gen_op_test_ne, | ||
| 62 | + gen_op_test_cs, | ||
| 63 | + gen_op_test_cc, | ||
| 64 | + gen_op_test_mi, | ||
| 65 | + gen_op_test_pl, | ||
| 66 | + gen_op_test_vs, | ||
| 67 | + gen_op_test_vc, | ||
| 68 | + gen_op_test_hi, | ||
| 69 | + gen_op_test_ls, | ||
| 70 | + gen_op_test_ge, | ||
| 71 | + gen_op_test_lt, | ||
| 72 | + gen_op_test_gt, | ||
| 73 | + gen_op_test_le, | ||
| 74 | +}; | ||
| 75 | + | ||
| 76 | +const uint8_t table_logic_cc[16] = { | ||
| 77 | + 1, /* and */ | ||
| 78 | + 1, /* xor */ | ||
| 79 | + 0, /* sub */ | ||
| 80 | + 0, /* rsb */ | ||
| 81 | + 0, /* add */ | ||
| 82 | + 0, /* adc */ | ||
| 83 | + 0, /* sbc */ | ||
| 84 | + 0, /* rsc */ | ||
| 85 | + 1, /* andl */ | ||
| 86 | + 1, /* xorl */ | ||
| 87 | + 0, /* cmp */ | ||
| 88 | + 0, /* cmn */ | ||
| 89 | + 1, /* orr */ | ||
| 90 | + 1, /* mov */ | ||
| 91 | + 1, /* bic */ | ||
| 92 | + 1, /* mvn */ | ||
| 93 | +}; | ||
| 94 | + | ||
| 95 | +static GenOpFunc1 *gen_shift_T1_im[4] = { | ||
| 96 | + gen_op_shll_T1_im, | ||
| 97 | + gen_op_shrl_T1_im, | ||
| 98 | + gen_op_sarl_T1_im, | ||
| 99 | + gen_op_rorl_T1_im, | ||
| 100 | +}; | ||
| 101 | + | ||
| 102 | +static GenOpFunc1 *gen_shift_T2_im[4] = { | ||
| 103 | + gen_op_shll_T2_im, | ||
| 104 | + gen_op_shrl_T2_im, | ||
| 105 | + gen_op_sarl_T2_im, | ||
| 106 | + gen_op_rorl_T2_im, | ||
| 107 | +}; | ||
| 108 | + | ||
| 109 | +static GenOpFunc1 *gen_shift_T1_im_cc[4] = { | ||
| 110 | + gen_op_shll_T1_im_cc, | ||
| 111 | + gen_op_shrl_T1_im_cc, | ||
| 112 | + gen_op_sarl_T1_im_cc, | ||
| 113 | + gen_op_rorl_T1_im_cc, | ||
| 114 | +}; | ||
| 115 | + | ||
| 116 | +static GenOpFunc *gen_shift_T1_T0[4] = { | ||
| 117 | + gen_op_shll_T1_T0, | ||
| 118 | + gen_op_shrl_T1_T0, | ||
| 119 | + gen_op_sarl_T1_T0, | ||
| 120 | + gen_op_rorl_T1_T0, | ||
| 121 | +}; | ||
| 122 | + | ||
| 123 | +static GenOpFunc *gen_shift_T1_T0_cc[4] = { | ||
| 124 | + gen_op_shll_T1_T0_cc, | ||
| 125 | + gen_op_shrl_T1_T0_cc, | ||
| 126 | + gen_op_sarl_T1_T0_cc, | ||
| 127 | + gen_op_rorl_T1_T0_cc, | ||
| 128 | +}; | ||
| 129 | + | ||
| 130 | +static GenOpFunc *gen_op_movl_TN_reg[3][16] = { | ||
| 131 | + { | ||
| 132 | + gen_op_movl_T0_r0, | ||
| 133 | + gen_op_movl_T0_r1, | ||
| 134 | + gen_op_movl_T0_r2, | ||
| 135 | + gen_op_movl_T0_r3, | ||
| 136 | + gen_op_movl_T0_r4, | ||
| 137 | + gen_op_movl_T0_r5, | ||
| 138 | + gen_op_movl_T0_r6, | ||
| 139 | + gen_op_movl_T0_r7, | ||
| 140 | + gen_op_movl_T0_r8, | ||
| 141 | + gen_op_movl_T0_r9, | ||
| 142 | + gen_op_movl_T0_r10, | ||
| 143 | + gen_op_movl_T0_r11, | ||
| 144 | + gen_op_movl_T0_r12, | ||
| 145 | + gen_op_movl_T0_r13, | ||
| 146 | + gen_op_movl_T0_r14, | ||
| 147 | + gen_op_movl_T0_r15, | ||
| 148 | + }, | ||
| 149 | + { | ||
| 150 | + gen_op_movl_T1_r0, | ||
| 151 | + gen_op_movl_T1_r1, | ||
| 152 | + gen_op_movl_T1_r2, | ||
| 153 | + gen_op_movl_T1_r3, | ||
| 154 | + gen_op_movl_T1_r4, | ||
| 155 | + gen_op_movl_T1_r5, | ||
| 156 | + gen_op_movl_T1_r6, | ||
| 157 | + gen_op_movl_T1_r7, | ||
| 158 | + gen_op_movl_T1_r8, | ||
| 159 | + gen_op_movl_T1_r9, | ||
| 160 | + gen_op_movl_T1_r10, | ||
| 161 | + gen_op_movl_T1_r11, | ||
| 162 | + gen_op_movl_T1_r12, | ||
| 163 | + gen_op_movl_T1_r13, | ||
| 164 | + gen_op_movl_T1_r14, | ||
| 165 | + gen_op_movl_T1_r15, | ||
| 166 | + }, | ||
| 167 | + { | ||
| 168 | + gen_op_movl_T2_r0, | ||
| 169 | + gen_op_movl_T2_r1, | ||
| 170 | + gen_op_movl_T2_r2, | ||
| 171 | + gen_op_movl_T2_r3, | ||
| 172 | + gen_op_movl_T2_r4, | ||
| 173 | + gen_op_movl_T2_r5, | ||
| 174 | + gen_op_movl_T2_r6, | ||
| 175 | + gen_op_movl_T2_r7, | ||
| 176 | + gen_op_movl_T2_r8, | ||
| 177 | + gen_op_movl_T2_r9, | ||
| 178 | + gen_op_movl_T2_r10, | ||
| 179 | + gen_op_movl_T2_r11, | ||
| 180 | + gen_op_movl_T2_r12, | ||
| 181 | + gen_op_movl_T2_r13, | ||
| 182 | + gen_op_movl_T2_r14, | ||
| 183 | + gen_op_movl_T2_r15, | ||
| 184 | + }, | ||
| 185 | +}; | ||
| 186 | + | ||
| 187 | +static GenOpFunc *gen_op_movl_reg_TN[2][16] = { | ||
| 188 | + { | ||
| 189 | + gen_op_movl_r0_T0, | ||
| 190 | + gen_op_movl_r1_T0, | ||
| 191 | + gen_op_movl_r2_T0, | ||
| 192 | + gen_op_movl_r3_T0, | ||
| 193 | + gen_op_movl_r4_T0, | ||
| 194 | + gen_op_movl_r5_T0, | ||
| 195 | + gen_op_movl_r6_T0, | ||
| 196 | + gen_op_movl_r7_T0, | ||
| 197 | + gen_op_movl_r8_T0, | ||
| 198 | + gen_op_movl_r9_T0, | ||
| 199 | + gen_op_movl_r10_T0, | ||
| 200 | + gen_op_movl_r11_T0, | ||
| 201 | + gen_op_movl_r12_T0, | ||
| 202 | + gen_op_movl_r13_T0, | ||
| 203 | + gen_op_movl_r14_T0, | ||
| 204 | + gen_op_movl_r15_T0, | ||
| 205 | + }, | ||
| 206 | + { | ||
| 207 | + gen_op_movl_r0_T1, | ||
| 208 | + gen_op_movl_r1_T1, | ||
| 209 | + gen_op_movl_r2_T1, | ||
| 210 | + gen_op_movl_r3_T1, | ||
| 211 | + gen_op_movl_r4_T1, | ||
| 212 | + gen_op_movl_r5_T1, | ||
| 213 | + gen_op_movl_r6_T1, | ||
| 214 | + gen_op_movl_r7_T1, | ||
| 215 | + gen_op_movl_r8_T1, | ||
| 216 | + gen_op_movl_r9_T1, | ||
| 217 | + gen_op_movl_r10_T1, | ||
| 218 | + gen_op_movl_r11_T1, | ||
| 219 | + gen_op_movl_r12_T1, | ||
| 220 | + gen_op_movl_r13_T1, | ||
| 221 | + gen_op_movl_r14_T1, | ||
| 222 | + gen_op_movl_r15_T1, | ||
| 223 | + }, | ||
| 224 | +}; | ||
| 225 | + | ||
| 226 | +static GenOpFunc1 *gen_op_movl_TN_im[3] = { | ||
| 227 | + gen_op_movl_T0_im, | ||
| 228 | + gen_op_movl_T1_im, | ||
| 229 | + gen_op_movl_T2_im, | ||
| 230 | +}; | ||
| 231 | + | ||
| 232 | +static inline void gen_movl_TN_reg(DisasContext *s, int reg, int t) | ||
| 233 | +{ | ||
| 234 | + int val; | ||
| 235 | + | ||
| 236 | + if (reg == 15) { | ||
| 237 | + /* normaly, since we updated PC, we need only to add 4 */ | ||
| 238 | + val = (long)s->pc + 4; | ||
| 239 | + gen_op_movl_TN_im[t](val); | ||
| 240 | + } else { | ||
| 241 | + gen_op_movl_TN_reg[t][reg](); | ||
| 242 | + } | ||
| 243 | +} | ||
| 244 | + | ||
| 245 | +static inline void gen_movl_T0_reg(DisasContext *s, int reg) | ||
| 246 | +{ | ||
| 247 | + gen_movl_TN_reg(s, reg, 0); | ||
| 248 | +} | ||
| 249 | + | ||
| 250 | +static inline void gen_movl_T1_reg(DisasContext *s, int reg) | ||
| 251 | +{ | ||
| 252 | + gen_movl_TN_reg(s, reg, 1); | ||
| 253 | +} | ||
| 254 | + | ||
| 255 | +static inline void gen_movl_T2_reg(DisasContext *s, int reg) | ||
| 256 | +{ | ||
| 257 | + gen_movl_TN_reg(s, reg, 2); | ||
| 258 | +} | ||
| 259 | + | ||
| 260 | +static inline void gen_movl_reg_TN(DisasContext *s, int reg, int t) | ||
| 261 | +{ | ||
| 262 | + gen_op_movl_reg_TN[t][reg](); | ||
| 263 | + if (reg == 15) { | ||
| 264 | + s->is_jmp = DISAS_JUMP; | ||
| 265 | + } | ||
| 266 | +} | ||
| 267 | + | ||
| 268 | +static inline void gen_movl_reg_T0(DisasContext *s, int reg) | ||
| 269 | +{ | ||
| 270 | + gen_movl_reg_TN(s, reg, 0); | ||
| 271 | +} | ||
| 272 | + | ||
| 273 | +static inline void gen_movl_reg_T1(DisasContext *s, int reg) | ||
| 274 | +{ | ||
| 275 | + gen_movl_reg_TN(s, reg, 1); | ||
| 276 | +} | ||
| 277 | + | ||
| 278 | +static inline void gen_add_data_offset(DisasContext *s, unsigned int insn) | ||
| 279 | +{ | ||
| 280 | + int val, rm, shift; | ||
| 281 | + | ||
| 282 | + if (!(insn & (1 << 25))) { | ||
| 283 | + /* immediate */ | ||
| 284 | + val = insn & 0xfff; | ||
| 285 | + if (!(insn & (1 << 23))) | ||
| 286 | + val = -val; | ||
| 287 | + gen_op_addl_T1_im(val); | ||
| 288 | + } else { | ||
| 289 | + /* shift/register */ | ||
| 290 | + rm = (insn) & 0xf; | ||
| 291 | + shift = (insn >> 7) & 0x1f; | ||
| 292 | + gen_movl_T2_reg(s, rm); | ||
| 293 | + if (shift != 0) { | ||
| 294 | + gen_shift_T2_im[(insn >> 5) & 3](shift); | ||
| 295 | + } | ||
| 296 | + if (!(insn & (1 << 23))) | ||
| 297 | + gen_op_subl_T1_T2(); | ||
| 298 | + else | ||
| 299 | + gen_op_addl_T1_T2(); | ||
| 300 | + } | ||
| 301 | +} | ||
| 302 | + | ||
| 303 | +static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn) | ||
| 304 | +{ | ||
| 305 | + int val, rm; | ||
| 306 | + | ||
| 307 | + if (insn & (1 << 22)) { | ||
| 308 | + /* immediate */ | ||
| 309 | + val = (insn & 0xf) | ((insn >> 4) & 0xf0); | ||
| 310 | + if (!(insn & (1 << 23))) | ||
| 311 | + val = -val; | ||
| 312 | + gen_op_addl_T1_im(val); | ||
| 313 | + } else { | ||
| 314 | + /* register */ | ||
| 315 | + rm = (insn) & 0xf; | ||
| 316 | + gen_movl_T2_reg(s, rm); | ||
| 317 | + if (!(insn & (1 << 23))) | ||
| 318 | + gen_op_subl_T1_T2(); | ||
| 319 | + else | ||
| 320 | + gen_op_addl_T1_T2(); | ||
| 321 | + } | ||
| 322 | +} | ||
| 323 | + | ||
| 324 | +static void disas_arm_insn(DisasContext *s) | ||
| 325 | +{ | ||
| 326 | + unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh; | ||
| 327 | + | ||
| 328 | + insn = ldl(s->pc); | ||
| 329 | + s->pc += 4; | ||
| 330 | + | ||
| 331 | + cond = insn >> 28; | ||
| 332 | + if (cond == 0xf) | ||
| 333 | + goto illegal_op; | ||
| 334 | + if (cond != 0xe) { | ||
| 335 | + /* if not always execute, we generate a conditional jump to | ||
| 336 | + next instruction */ | ||
| 337 | + gen_test_cc[cond ^ 1]((long)s->tb, (long)s->pc); | ||
| 338 | + s->is_jmp = DISAS_JUMP_NEXT; | ||
| 339 | + } | ||
| 340 | + if (((insn & 0x0e000000) == 0 && | ||
| 341 | + (insn & 0x00000090) != 0x90) || | ||
| 342 | + ((insn & 0x0e000000) == (1 << 25))) { | ||
| 343 | + int set_cc, logic_cc, shiftop; | ||
| 344 | + | ||
| 345 | + op1 = (insn >> 21) & 0xf; | ||
| 346 | + set_cc = (insn >> 20) & 1; | ||
| 347 | + logic_cc = table_logic_cc[op1] & set_cc; | ||
| 348 | + | ||
| 349 | + /* data processing instruction */ | ||
| 350 | + if (insn & (1 << 25)) { | ||
| 351 | + /* immediate operand */ | ||
| 352 | + val = insn & 0xff; | ||
| 353 | + shift = ((insn >> 8) & 0xf) * 2; | ||
| 354 | + if (shift) | ||
| 355 | + val = (val >> shift) | (val << (32 - shift)); | ||
| 356 | + gen_op_movl_T1_im(val); | ||
| 357 | + /* XXX: is CF modified ? */ | ||
| 358 | + } else { | ||
| 359 | + /* register */ | ||
| 360 | + rm = (insn) & 0xf; | ||
| 361 | + gen_movl_T1_reg(s, rm); | ||
| 362 | + shiftop = (insn >> 5) & 3; | ||
| 363 | + if (!(insn & (1 << 4))) { | ||
| 364 | + shift = (insn >> 7) & 0x1f; | ||
| 365 | + if (shift != 0) { | ||
| 366 | + if (logic_cc) { | ||
| 367 | + gen_shift_T1_im_cc[shiftop](shift); | ||
| 368 | + } else { | ||
| 369 | + gen_shift_T1_im[shiftop](shift); | ||
| 370 | + } | ||
| 371 | + } | ||
| 372 | + } else { | ||
| 373 | + rs = (insn >> 8) & 0xf; | ||
| 374 | + gen_movl_T0_reg(s, rs); | ||
| 375 | + if (logic_cc) { | ||
| 376 | + gen_shift_T1_T0_cc[shiftop](); | ||
| 377 | + } else { | ||
| 378 | + gen_shift_T1_T0[shiftop](); | ||
| 379 | + } | ||
| 380 | + } | ||
| 381 | + } | ||
| 382 | + if (op1 != 0x0f && op1 != 0x0d) { | ||
| 383 | + rn = (insn >> 16) & 0xf; | ||
| 384 | + gen_movl_T0_reg(s, rn); | ||
| 385 | + } | ||
| 386 | + rd = (insn >> 12) & 0xf; | ||
| 387 | + switch(op1) { | ||
| 388 | + case 0x00: | ||
| 389 | + gen_op_andl_T0_T1(); | ||
| 390 | + gen_movl_reg_T0(s, rd); | ||
| 391 | + if (logic_cc) | ||
| 392 | + gen_op_logic_T0_cc(); | ||
| 393 | + break; | ||
| 394 | + case 0x01: | ||
| 395 | + gen_op_xorl_T0_T1(); | ||
| 396 | + gen_movl_reg_T0(s, rd); | ||
| 397 | + if (logic_cc) | ||
| 398 | + gen_op_logic_T0_cc(); | ||
| 399 | + break; | ||
| 400 | + case 0x02: | ||
| 401 | + if (set_cc) | ||
| 402 | + gen_op_subl_T0_T1_cc(); | ||
| 403 | + else | ||
| 404 | + gen_op_subl_T0_T1(); | ||
| 405 | + gen_movl_reg_T0(s, rd); | ||
| 406 | + break; | ||
| 407 | + case 0x03: | ||
| 408 | + if (set_cc) | ||
| 409 | + gen_op_rsbl_T0_T1_cc(); | ||
| 410 | + else | ||
| 411 | + gen_op_rsbl_T0_T1(); | ||
| 412 | + gen_movl_reg_T0(s, rd); | ||
| 413 | + break; | ||
| 414 | + case 0x04: | ||
| 415 | + if (set_cc) | ||
| 416 | + gen_op_addl_T0_T1_cc(); | ||
| 417 | + else | ||
| 418 | + gen_op_addl_T0_T1(); | ||
| 419 | + gen_movl_reg_T0(s, rd); | ||
| 420 | + break; | ||
| 421 | + case 0x05: | ||
| 422 | + if (set_cc) | ||
| 423 | + gen_op_adcl_T0_T1_cc(); | ||
| 424 | + else | ||
| 425 | + gen_op_adcl_T0_T1(); | ||
| 426 | + gen_movl_reg_T0(s, rd); | ||
| 427 | + break; | ||
| 428 | + case 0x06: | ||
| 429 | + if (set_cc) | ||
| 430 | + gen_op_sbcl_T0_T1_cc(); | ||
| 431 | + else | ||
| 432 | + gen_op_sbcl_T0_T1(); | ||
| 433 | + gen_movl_reg_T0(s, rd); | ||
| 434 | + break; | ||
| 435 | + case 0x07: | ||
| 436 | + if (set_cc) | ||
| 437 | + gen_op_rscl_T0_T1_cc(); | ||
| 438 | + else | ||
| 439 | + gen_op_rscl_T0_T1(); | ||
| 440 | + gen_movl_reg_T0(s, rd); | ||
| 441 | + break; | ||
| 442 | + case 0x08: | ||
| 443 | + if (set_cc) { | ||
| 444 | + gen_op_andl_T0_T1(); | ||
| 445 | + gen_op_logic_T0_cc(); | ||
| 446 | + } | ||
| 447 | + break; | ||
| 448 | + case 0x09: | ||
| 449 | + if (set_cc) { | ||
| 450 | + gen_op_xorl_T0_T1(); | ||
| 451 | + gen_op_logic_T0_cc(); | ||
| 452 | + } | ||
| 453 | + break; | ||
| 454 | + case 0x0a: | ||
| 455 | + if (set_cc) { | ||
| 456 | + gen_op_subl_T0_T1_cc(); | ||
| 457 | + } | ||
| 458 | + break; | ||
| 459 | + case 0x0b: | ||
| 460 | + if (set_cc) { | ||
| 461 | + gen_op_addl_T0_T1_cc(); | ||
| 462 | + } | ||
| 463 | + break; | ||
| 464 | + case 0x0c: | ||
| 465 | + gen_op_orl_T0_T1(); | ||
| 466 | + gen_movl_reg_T0(s, rd); | ||
| 467 | + if (logic_cc) | ||
| 468 | + gen_op_logic_T0_cc(); | ||
| 469 | + break; | ||
| 470 | + case 0x0d: | ||
| 471 | + gen_movl_reg_T1(s, rd); | ||
| 472 | + if (logic_cc) | ||
| 473 | + gen_op_logic_T1_cc(); | ||
| 474 | + break; | ||
| 475 | + case 0x0e: | ||
| 476 | + gen_op_bicl_T0_T1(); | ||
| 477 | + gen_movl_reg_T0(s, rd); | ||
| 478 | + if (logic_cc) | ||
| 479 | + gen_op_logic_T0_cc(); | ||
| 480 | + break; | ||
| 481 | + default: | ||
| 482 | + case 0x0f: | ||
| 483 | + gen_op_notl_T1(); | ||
| 484 | + gen_movl_reg_T1(s, rd); | ||
| 485 | + if (logic_cc) | ||
| 486 | + gen_op_logic_T1_cc(); | ||
| 487 | + break; | ||
| 488 | + } | ||
| 489 | + } else { | ||
| 490 | + /* other instructions */ | ||
| 491 | + op1 = (insn >> 24) & 0xf; | ||
| 492 | + switch(op1) { | ||
| 493 | + case 0x0: | ||
| 494 | + case 0x1: | ||
| 495 | + sh = (insn >> 5) & 3; | ||
| 496 | + if (sh == 0) { | ||
| 497 | + if (op1 == 0x0) { | ||
| 498 | + rd = (insn >> 16) & 0xf; | ||
| 499 | + rn = (insn >> 12) & 0xf; | ||
| 500 | + rs = (insn >> 8) & 0xf; | ||
| 501 | + rm = (insn) & 0xf; | ||
| 502 | + if (!(insn & (1 << 23))) { | ||
| 503 | + /* 32 bit mul */ | ||
| 504 | + gen_movl_T0_reg(s, rs); | ||
| 505 | + gen_movl_T1_reg(s, rm); | ||
| 506 | + gen_op_mul_T0_T1(); | ||
| 507 | + if (insn & (1 << 21)) { | ||
| 508 | + gen_movl_T1_reg(s, rn); | ||
| 509 | + gen_op_addl_T0_T1(); | ||
| 510 | + } | ||
| 511 | + if (insn & (1 << 20)) | ||
| 512 | + gen_op_logic_T0_cc(); | ||
| 513 | + gen_movl_reg_T0(s, rd); | ||
| 514 | + } else { | ||
| 515 | + /* 64 bit mul */ | ||
| 516 | + gen_movl_T0_reg(s, rs); | ||
| 517 | + gen_movl_T1_reg(s, rm); | ||
| 518 | + if (insn & (1 << 22)) | ||
| 519 | + gen_op_mull_T0_T1(); | ||
| 520 | + else | ||
| 521 | + gen_op_imull_T0_T1(); | ||
| 522 | + if (insn & (1 << 21)) | ||
| 523 | + gen_op_addq_T0_T1(rn, rd); | ||
| 524 | + if (insn & (1 << 20)) | ||
| 525 | + gen_op_logicq_cc(); | ||
| 526 | + gen_movl_reg_T0(s, rn); | ||
| 527 | + gen_movl_reg_T1(s, rd); | ||
| 528 | + } | ||
| 529 | + } else { | ||
| 530 | + /* SWP instruction */ | ||
| 531 | + rn = (insn >> 16) & 0xf; | ||
| 532 | + rd = (insn >> 12) & 0xf; | ||
| 533 | + rm = (insn) & 0xf; | ||
| 534 | + | ||
| 535 | + gen_movl_T0_reg(s, rm); | ||
| 536 | + gen_movl_T1_reg(s, rn); | ||
| 537 | + if (insn & (1 << 22)) { | ||
| 538 | + gen_op_swpb_T0_T1(); | ||
| 539 | + } else { | ||
| 540 | + gen_op_swpl_T0_T1(); | ||
| 541 | + } | ||
| 542 | + gen_movl_reg_T0(s, rd); | ||
| 543 | + } | ||
| 544 | + } else { | ||
| 545 | + /* load/store half word */ | ||
| 546 | + rn = (insn >> 16) & 0xf; | ||
| 547 | + rd = (insn >> 12) & 0xf; | ||
| 548 | + gen_movl_T1_reg(s, rn); | ||
| 549 | + if (insn & (1 << 25)) | ||
| 550 | + gen_add_datah_offset(s, insn); | ||
| 551 | + if (insn & (1 << 20)) { | ||
| 552 | + /* load */ | ||
| 553 | + switch(sh) { | ||
| 554 | + case 1: | ||
| 555 | + gen_op_lduw_T0_T1(); | ||
| 556 | + break; | ||
| 557 | + case 2: | ||
| 558 | + gen_op_ldsb_T0_T1(); | ||
| 559 | + break; | ||
| 560 | + default: | ||
| 561 | + case 3: | ||
| 562 | + gen_op_ldsw_T0_T1(); | ||
| 563 | + break; | ||
| 564 | + } | ||
| 565 | + } else { | ||
| 566 | + /* store */ | ||
| 567 | + gen_op_stw_T0_T1(); | ||
| 568 | + } | ||
| 569 | + if (!(insn & (1 << 24))) { | ||
| 570 | + gen_add_datah_offset(s, insn); | ||
| 571 | + gen_movl_reg_T1(s, rn); | ||
| 572 | + } else if (insn & (1 << 21)) { | ||
| 573 | + gen_movl_reg_T1(s, rn); | ||
| 574 | + } | ||
| 575 | + } | ||
| 576 | + break; | ||
| 577 | + case 0x4: | ||
| 578 | + case 0x5: | ||
| 579 | + case 0x6: | ||
| 580 | + case 0x7: | ||
| 581 | + /* load/store byte/word */ | ||
| 582 | + rn = (insn >> 16) & 0xf; | ||
| 583 | + rd = (insn >> 12) & 0xf; | ||
| 584 | + gen_movl_T1_reg(s, rn); | ||
| 585 | + if (insn & (1 << 24)) | ||
| 586 | + gen_add_data_offset(s, insn); | ||
| 587 | + if (insn & (1 << 20)) { | ||
| 588 | + /* load */ | ||
| 589 | + if (insn & (1 << 22)) | ||
| 590 | + gen_op_ldub_T0_T1(); | ||
| 591 | + else | ||
| 592 | + gen_op_ldl_T0_T1(); | ||
| 593 | + gen_movl_reg_T0(s, rd); | ||
| 594 | + } else { | ||
| 595 | + /* store */ | ||
| 596 | + gen_movl_T0_reg(s, rd); | ||
| 597 | + if (insn & (1 << 22)) | ||
| 598 | + gen_op_stb_T0_T1(); | ||
| 599 | + else | ||
| 600 | + gen_op_stl_T0_T1(); | ||
| 601 | + } | ||
| 602 | + if (!(insn & (1 << 24))) { | ||
| 603 | + gen_add_data_offset(s, insn); | ||
| 604 | + gen_movl_reg_T1(s, rn); | ||
| 605 | + } else if (insn & (1 << 21)) | ||
| 606 | + gen_movl_reg_T1(s, rn); { | ||
| 607 | + } | ||
| 608 | + break; | ||
| 609 | + case 0x08: | ||
| 610 | + case 0x09: | ||
| 611 | + { | ||
| 612 | + int j, n; | ||
| 613 | + /* load/store multiple words */ | ||
| 614 | + /* XXX: store correct base if write back */ | ||
| 615 | + if (insn & (1 << 22)) | ||
| 616 | + goto illegal_op; /* only usable in supervisor mode */ | ||
| 617 | + rn = (insn >> 16) & 0xf; | ||
| 618 | + gen_movl_T1_reg(s, rn); | ||
| 619 | + | ||
| 620 | + /* compute total size */ | ||
| 621 | + n = 0; | ||
| 622 | + for(i=0;i<16;i++) { | ||
| 623 | + if (insn & (1 << i)) | ||
| 624 | + n++; | ||
| 625 | + } | ||
| 626 | + /* XXX: test invalid n == 0 case ? */ | ||
| 627 | + if (insn & (1 << 23)) { | ||
| 628 | + if (insn & (1 << 24)) { | ||
| 629 | + /* pre increment */ | ||
| 630 | + gen_op_addl_T1_im(4); | ||
| 631 | + } else { | ||
| 632 | + /* post increment */ | ||
| 633 | + } | ||
| 634 | + } else { | ||
| 635 | + if (insn & (1 << 24)) { | ||
| 636 | + /* pre decrement */ | ||
| 637 | + gen_op_addl_T1_im(-(n * 4)); | ||
| 638 | + } else { | ||
| 639 | + /* post decrement */ | ||
| 640 | + if (n != 1) | ||
| 641 | + gen_op_addl_T1_im(-((n - 1) * 4)); | ||
| 642 | + } | ||
| 643 | + } | ||
| 644 | + j = 0; | ||
| 645 | + for(i=0;i<16;i++) { | ||
| 646 | + if (insn & (1 << i)) { | ||
| 647 | + if (insn & (1 << 20)) { | ||
| 648 | + /* load */ | ||
| 649 | + gen_op_ldl_T0_T1(); | ||
| 650 | + gen_movl_reg_T0(s, i); | ||
| 651 | + } else { | ||
| 652 | + /* store */ | ||
| 653 | + if (i == 15) { | ||
| 654 | + /* special case: r15 = PC + 12 */ | ||
| 655 | + val = (long)s->pc + 8; | ||
| 656 | + gen_op_movl_TN_im[0](val); | ||
| 657 | + } else { | ||
| 658 | + gen_movl_T0_reg(s, i); | ||
| 659 | + } | ||
| 660 | + gen_op_stl_T0_T1(); | ||
| 661 | + } | ||
| 662 | + j++; | ||
| 663 | + /* no need to add after the last transfer */ | ||
| 664 | + if (j != n) | ||
| 665 | + gen_op_addl_T1_im(4); | ||
| 666 | + } | ||
| 667 | + } | ||
| 668 | + if (insn & (1 << 21)) { | ||
| 669 | + /* write back */ | ||
| 670 | + if (insn & (1 << 23)) { | ||
| 671 | + if (insn & (1 << 24)) { | ||
| 672 | + /* pre increment */ | ||
| 673 | + } else { | ||
| 674 | + /* post increment */ | ||
| 675 | + gen_op_addl_T1_im(4); | ||
| 676 | + } | ||
| 677 | + } else { | ||
| 678 | + if (insn & (1 << 24)) { | ||
| 679 | + /* pre decrement */ | ||
| 680 | + if (n != 1) | ||
| 681 | + gen_op_addl_T1_im(-((n - 1) * 4)); | ||
| 682 | + } else { | ||
| 683 | + /* post decrement */ | ||
| 684 | + gen_op_addl_T1_im(-(n * 4)); | ||
| 685 | + } | ||
| 686 | + } | ||
| 687 | + gen_movl_reg_T1(s, rn); | ||
| 688 | + } | ||
| 689 | + } | ||
| 690 | + break; | ||
| 691 | + case 0xa: | ||
| 692 | + case 0xb: | ||
| 693 | + { | ||
| 694 | + int offset; | ||
| 695 | + | ||
| 696 | + /* branch (and link) */ | ||
| 697 | + val = (int)s->pc; | ||
| 698 | + if (insn & (1 << 24)) { | ||
| 699 | + gen_op_movl_T0_im(val); | ||
| 700 | + gen_op_movl_reg_TN[0][14](); | ||
| 701 | + } | ||
| 702 | + offset = (((int)insn << 8) >> 8); | ||
| 703 | + val += (offset << 2) + 4; | ||
| 704 | + gen_op_jmp((long)s->tb, val); | ||
| 705 | + s->is_jmp = DISAS_TB_JUMP; | ||
| 706 | + } | ||
| 707 | + break; | ||
| 708 | + case 0xf: | ||
| 709 | + /* swi */ | ||
| 710 | + gen_op_movl_T0_im((long)s->pc); | ||
| 711 | + gen_op_movl_reg_TN[0][15](); | ||
| 712 | + gen_op_swi(); | ||
| 713 | + s->is_jmp = DISAS_JUMP; | ||
| 714 | + break; | ||
| 715 | + case 0xc: | ||
| 716 | + case 0xd: | ||
| 717 | + rd = (insn >> 12) & 0x7; | ||
| 718 | + rn = (insn >> 16) & 0xf; | ||
| 719 | + gen_movl_T1_reg(s, rn); | ||
| 720 | + val = (insn) & 0xff; | ||
| 721 | + if (!(insn & (1 << 23))) | ||
| 722 | + val = -val; | ||
| 723 | + switch((insn >> 8) & 0xf) { | ||
| 724 | + case 0x1: | ||
| 725 | + /* load/store */ | ||
| 726 | + if ((insn & (1 << 24))) | ||
| 727 | + gen_op_addl_T1_im(val); | ||
| 728 | + /* XXX: do it */ | ||
| 729 | + if (!(insn & (1 << 24))) | ||
| 730 | + gen_op_addl_T1_im(val); | ||
| 731 | + if (insn & (1 << 21)) | ||
| 732 | + gen_movl_reg_T1(s, rn); | ||
| 733 | + break; | ||
| 734 | + case 0x2: | ||
| 735 | + { | ||
| 736 | + int n, i; | ||
| 737 | + /* load store multiple */ | ||
| 738 | + if ((insn & (1 << 24))) | ||
| 739 | + gen_op_addl_T1_im(val); | ||
| 740 | + switch(insn & 0x00408000) { | ||
| 741 | + case 0x00008000: n = 1; break; | ||
| 742 | + case 0x00400000: n = 2; break; | ||
| 743 | + case 0x00408000: n = 3; break; | ||
| 744 | + default: n = 4; break; | ||
| 745 | + } | ||
| 746 | + for(i = 0;i < n; i++) { | ||
| 747 | + /* XXX: do it */ | ||
| 748 | + } | ||
| 749 | + if (!(insn & (1 << 24))) | ||
| 750 | + gen_op_addl_T1_im(val); | ||
| 751 | + if (insn & (1 << 21)) | ||
| 752 | + gen_movl_reg_T1(s, rn); | ||
| 753 | + } | ||
| 754 | + break; | ||
| 755 | + default: | ||
| 756 | + goto illegal_op; | ||
| 757 | + } | ||
| 758 | + break; | ||
| 759 | + case 0x0e: | ||
| 760 | + /* float ops */ | ||
| 761 | + /* XXX: do it */ | ||
| 762 | + switch((insn >> 20) & 0xf) { | ||
| 763 | + case 0x2: /* wfs */ | ||
| 764 | + break; | ||
| 765 | + case 0x3: /* rfs */ | ||
| 766 | + break; | ||
| 767 | + case 0x4: /* wfc */ | ||
| 768 | + break; | ||
| 769 | + case 0x5: /* rfc */ | ||
| 770 | + break; | ||
| 771 | + default: | ||
| 772 | + goto illegal_op; | ||
| 773 | + } | ||
| 774 | + break; | ||
| 775 | + default: | ||
| 776 | + illegal_op: | ||
| 777 | + gen_op_movl_T0_im((long)s->pc - 4); | ||
| 778 | + gen_op_movl_reg_TN[0][15](); | ||
| 779 | + gen_op_undef_insn(); | ||
| 780 | + s->is_jmp = DISAS_JUMP; | ||
| 781 | + break; | ||
| 782 | + } | ||
| 783 | + } | ||
| 784 | +} | ||
| 785 | + | ||
| 786 | +/* generate intermediate code in gen_opc_buf and gen_opparam_buf for | ||
| 787 | + basic block 'tb'. If search_pc is TRUE, also generate PC | ||
| 788 | + information for each intermediate instruction. */ | ||
| 789 | +static inline int gen_intermediate_code_internal(CPUState *env, | ||
| 790 | + TranslationBlock *tb, | ||
| 791 | + int search_pc) | ||
| 792 | +{ | ||
| 793 | + DisasContext dc1, *dc = &dc1; | ||
| 794 | + uint16_t *gen_opc_end; | ||
| 795 | + int j, lj; | ||
| 796 | + uint8_t *pc_start; | ||
| 797 | + | ||
| 798 | + /* generate intermediate code */ | ||
| 799 | + pc_start = (uint8_t *)tb->pc; | ||
| 800 | + | ||
| 801 | + dc->tb = tb; | ||
| 802 | + | ||
| 803 | + gen_opc_ptr = gen_opc_buf; | ||
| 804 | + gen_opc_end = gen_opc_buf + OPC_MAX_SIZE; | ||
| 805 | + gen_opparam_ptr = gen_opparam_buf; | ||
| 806 | + | ||
| 807 | + dc->is_jmp = DISAS_NEXT; | ||
| 808 | + dc->pc = pc_start; | ||
| 809 | + lj = -1; | ||
| 810 | + do { | ||
| 811 | + if (search_pc) { | ||
| 812 | + j = gen_opc_ptr - gen_opc_buf; | ||
| 813 | + if (lj < j) { | ||
| 814 | + lj++; | ||
| 815 | + while (lj < j) | ||
| 816 | + gen_opc_instr_start[lj++] = 0; | ||
| 817 | + } | ||
| 818 | + gen_opc_pc[lj] = (uint32_t)dc->pc; | ||
| 819 | + gen_opc_instr_start[lj] = 1; | ||
| 820 | + } | ||
| 821 | + disas_arm_insn(dc); | ||
| 822 | + } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end && | ||
| 823 | + (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32)); | ||
| 824 | + switch(dc->is_jmp) { | ||
| 825 | + case DISAS_JUMP_NEXT: | ||
| 826 | + case DISAS_NEXT: | ||
| 827 | + gen_op_jmp((long)dc->tb, (long)dc->pc); | ||
| 828 | + break; | ||
| 829 | + default: | ||
| 830 | + case DISAS_JUMP: | ||
| 831 | + /* indicate that the hash table must be used to find the next TB */ | ||
| 832 | + gen_op_movl_T0_0(); | ||
| 833 | + gen_op_exit_tb(); | ||
| 834 | + break; | ||
| 835 | + case DISAS_TB_JUMP: | ||
| 836 | + /* nothing more to generate */ | ||
| 837 | + break; | ||
| 838 | + } | ||
| 839 | + *gen_opc_ptr = INDEX_op_end; | ||
| 840 | + | ||
| 841 | +#ifdef DEBUG_DISAS | ||
| 842 | + if (loglevel) { | ||
| 843 | + fprintf(logfile, "----------------\n"); | ||
| 844 | + fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start)); | ||
| 845 | + disas(logfile, pc_start, dc->pc - pc_start, 0, 0); | ||
| 846 | + fprintf(logfile, "\n"); | ||
| 847 | + | ||
| 848 | + fprintf(logfile, "OP:\n"); | ||
| 849 | + dump_ops(gen_opc_buf, gen_opparam_buf); | ||
| 850 | + fprintf(logfile, "\n"); | ||
| 851 | + } | ||
| 852 | +#endif | ||
| 853 | + if (!search_pc) | ||
| 854 | + tb->size = dc->pc - pc_start; | ||
| 855 | + return 0; | ||
| 856 | +} | ||
| 857 | + | ||
| 858 | +int gen_intermediate_code(CPUState *env, TranslationBlock *tb) | ||
| 859 | +{ | ||
| 860 | + return gen_intermediate_code_internal(env, tb, 0); | ||
| 861 | +} | ||
| 862 | + | ||
| 863 | +int gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb) | ||
| 864 | +{ | ||
| 865 | + return gen_intermediate_code_internal(env, tb, 1); | ||
| 866 | +} | ||
| 867 | + | ||
| 868 | +CPUARMState *cpu_arm_init(void) | ||
| 869 | +{ | ||
| 870 | + CPUARMState *env; | ||
| 871 | + | ||
| 872 | + cpu_exec_init(); | ||
| 873 | + | ||
| 874 | + env = malloc(sizeof(CPUARMState)); | ||
| 875 | + if (!env) | ||
| 876 | + return NULL; | ||
| 877 | + memset(env, 0, sizeof(CPUARMState)); | ||
| 878 | + return env; | ||
| 879 | +} | ||
| 880 | + | ||
| 881 | +void cpu_arm_close(CPUARMState *env) | ||
| 882 | +{ | ||
| 883 | + free(env); | ||
| 884 | +} | ||
| 885 | + | ||
| 886 | +void cpu_arm_dump_state(CPUARMState *env, FILE *f, int flags) | ||
| 887 | +{ | ||
| 888 | + int i; | ||
| 889 | + | ||
| 890 | + for(i=0;i<16;i++) { | ||
| 891 | + fprintf(f, "R%02d=%08x", i, env->regs[i]); | ||
| 892 | + if ((i % 4) == 3) | ||
| 893 | + fprintf(f, "\n"); | ||
| 894 | + else | ||
| 895 | + fprintf(f, " "); | ||
| 896 | + } | ||
| 897 | + fprintf(f, "PSR=%08x %c%c%c%c\n", | ||
| 898 | + env->cpsr, | ||
| 899 | + env->cpsr & (1 << 31) ? 'N' : '-', | ||
| 900 | + env->cpsr & (1 << 30) ? 'Z' : '-', | ||
| 901 | + env->cpsr & (1 << 29) ? 'C' : '-', | ||
| 902 | + env->cpsr & (1 << 28) ? 'V' : '-'); | ||
| 903 | +} |
target-i386/cpu.h
0 → 100644
| 1 | +/* | ||
| 2 | + * i386 virtual CPU header | ||
| 3 | + * | ||
| 4 | + * Copyright (c) 2003 Fabrice Bellard | ||
| 5 | + * | ||
| 6 | + * This library is free software; you can redistribute it and/or | ||
| 7 | + * modify it under the terms of the GNU Lesser General Public | ||
| 8 | + * License as published by the Free Software Foundation; either | ||
| 9 | + * version 2 of the License, or (at your option) any later version. | ||
| 10 | + * | ||
| 11 | + * This library is distributed in the hope that it will be useful, | ||
| 12 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 14 | + * Lesser General Public License for more details. | ||
| 15 | + * | ||
| 16 | + * You should have received a copy of the GNU Lesser General Public | ||
| 17 | + * License along with this library; if not, write to the Free Software | ||
| 18 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 19 | + */ | ||
| 20 | +#ifndef CPU_I386_H | ||
| 21 | +#define CPU_I386_H | ||
| 22 | + | ||
| 23 | +#include "cpu-defs.h" | ||
| 24 | + | ||
| 25 | +#define R_EAX 0 | ||
| 26 | +#define R_ECX 1 | ||
| 27 | +#define R_EDX 2 | ||
| 28 | +#define R_EBX 3 | ||
| 29 | +#define R_ESP 4 | ||
| 30 | +#define R_EBP 5 | ||
| 31 | +#define R_ESI 6 | ||
| 32 | +#define R_EDI 7 | ||
| 33 | + | ||
| 34 | +#define R_AL 0 | ||
| 35 | +#define R_CL 1 | ||
| 36 | +#define R_DL 2 | ||
| 37 | +#define R_BL 3 | ||
| 38 | +#define R_AH 4 | ||
| 39 | +#define R_CH 5 | ||
| 40 | +#define R_DH 6 | ||
| 41 | +#define R_BH 7 | ||
| 42 | + | ||
| 43 | +#define R_ES 0 | ||
| 44 | +#define R_CS 1 | ||
| 45 | +#define R_SS 2 | ||
| 46 | +#define R_DS 3 | ||
| 47 | +#define R_FS 4 | ||
| 48 | +#define R_GS 5 | ||
| 49 | + | ||
| 50 | +/* segment descriptor fields */ | ||
| 51 | +#define DESC_G_MASK (1 << 23) | ||
| 52 | +#define DESC_B_SHIFT 22 | ||
| 53 | +#define DESC_B_MASK (1 << DESC_B_SHIFT) | ||
| 54 | +#define DESC_AVL_MASK (1 << 20) | ||
| 55 | +#define DESC_P_MASK (1 << 15) | ||
| 56 | +#define DESC_DPL_SHIFT 13 | ||
| 57 | +#define DESC_S_MASK (1 << 12) | ||
| 58 | +#define DESC_TYPE_SHIFT 8 | ||
| 59 | +#define DESC_A_MASK (1 << 8) | ||
| 60 | + | ||
| 61 | +#define DESC_CS_MASK (1 << 11) | ||
| 62 | +#define DESC_C_MASK (1 << 10) | ||
| 63 | +#define DESC_R_MASK (1 << 9) | ||
| 64 | + | ||
| 65 | +#define DESC_E_MASK (1 << 10) | ||
| 66 | +#define DESC_W_MASK (1 << 9) | ||
| 67 | + | ||
| 68 | +/* eflags masks */ | ||
| 69 | +#define CC_C 0x0001 | ||
| 70 | +#define CC_P 0x0004 | ||
| 71 | +#define CC_A 0x0010 | ||
| 72 | +#define CC_Z 0x0040 | ||
| 73 | +#define CC_S 0x0080 | ||
| 74 | +#define CC_O 0x0800 | ||
| 75 | + | ||
| 76 | +#define TF_SHIFT 8 | ||
| 77 | +#define IOPL_SHIFT 12 | ||
| 78 | +#define VM_SHIFT 17 | ||
| 79 | + | ||
| 80 | +#define TF_MASK 0x00000100 | ||
| 81 | +#define IF_MASK 0x00000200 | ||
| 82 | +#define DF_MASK 0x00000400 | ||
| 83 | +#define IOPL_MASK 0x00003000 | ||
| 84 | +#define NT_MASK 0x00004000 | ||
| 85 | +#define RF_MASK 0x00010000 | ||
| 86 | +#define VM_MASK 0x00020000 | ||
| 87 | +#define AC_MASK 0x00040000 | ||
| 88 | +#define VIF_MASK 0x00080000 | ||
| 89 | +#define VIP_MASK 0x00100000 | ||
| 90 | +#define ID_MASK 0x00200000 | ||
| 91 | + | ||
| 92 | +/* hidden flags - used internally by qemu to represent additionnal cpu | ||
| 93 | + states. Only the CPL and INHIBIT_IRQ are not redundant. We avoid | ||
| 94 | + using the IOPL_MASK, TF_MASK and VM_MASK bit position to ease oring | ||
| 95 | + with eflags. */ | ||
| 96 | +/* current cpl */ | ||
| 97 | +#define HF_CPL_SHIFT 0 | ||
| 98 | +/* true if soft mmu is being used */ | ||
| 99 | +#define HF_SOFTMMU_SHIFT 2 | ||
| 100 | +/* true if hardware interrupts must be disabled for next instruction */ | ||
| 101 | +#define HF_INHIBIT_IRQ_SHIFT 3 | ||
| 102 | +/* 16 or 32 segments */ | ||
| 103 | +#define HF_CS32_SHIFT 4 | ||
| 104 | +#define HF_SS32_SHIFT 5 | ||
| 105 | +/* zero base for DS, ES and SS */ | ||
| 106 | +#define HF_ADDSEG_SHIFT 6 | ||
| 107 | + | ||
| 108 | +#define HF_CPL_MASK (3 << HF_CPL_SHIFT) | ||
| 109 | +#define HF_SOFTMMU_MASK (1 << HF_SOFTMMU_SHIFT) | ||
| 110 | +#define HF_INHIBIT_IRQ_MASK (1 << HF_INHIBIT_IRQ_SHIFT) | ||
| 111 | +#define HF_CS32_MASK (1 << HF_CS32_SHIFT) | ||
| 112 | +#define HF_SS32_MASK (1 << HF_SS32_SHIFT) | ||
| 113 | +#define HF_ADDSEG_MASK (1 << HF_ADDSEG_SHIFT) | ||
| 114 | + | ||
| 115 | +#define CR0_PE_MASK (1 << 0) | ||
| 116 | +#define CR0_TS_MASK (1 << 3) | ||
| 117 | +#define CR0_WP_MASK (1 << 16) | ||
| 118 | +#define CR0_AM_MASK (1 << 18) | ||
| 119 | +#define CR0_PG_MASK (1 << 31) | ||
| 120 | + | ||
| 121 | +#define CR4_VME_MASK (1 << 0) | ||
| 122 | +#define CR4_PVI_MASK (1 << 1) | ||
| 123 | +#define CR4_TSD_MASK (1 << 2) | ||
| 124 | +#define CR4_DE_MASK (1 << 3) | ||
| 125 | +#define CR4_PSE_MASK (1 << 4) | ||
| 126 | + | ||
| 127 | +#define PG_PRESENT_BIT 0 | ||
| 128 | +#define PG_RW_BIT 1 | ||
| 129 | +#define PG_USER_BIT 2 | ||
| 130 | +#define PG_PWT_BIT 3 | ||
| 131 | +#define PG_PCD_BIT 4 | ||
| 132 | +#define PG_ACCESSED_BIT 5 | ||
| 133 | +#define PG_DIRTY_BIT 6 | ||
| 134 | +#define PG_PSE_BIT 7 | ||
| 135 | +#define PG_GLOBAL_BIT 8 | ||
| 136 | + | ||
| 137 | +#define PG_PRESENT_MASK (1 << PG_PRESENT_BIT) | ||
| 138 | +#define PG_RW_MASK (1 << PG_RW_BIT) | ||
| 139 | +#define PG_USER_MASK (1 << PG_USER_BIT) | ||
| 140 | +#define PG_PWT_MASK (1 << PG_PWT_BIT) | ||
| 141 | +#define PG_PCD_MASK (1 << PG_PCD_BIT) | ||
| 142 | +#define PG_ACCESSED_MASK (1 << PG_ACCESSED_BIT) | ||
| 143 | +#define PG_DIRTY_MASK (1 << PG_DIRTY_BIT) | ||
| 144 | +#define PG_PSE_MASK (1 << PG_PSE_BIT) | ||
| 145 | +#define PG_GLOBAL_MASK (1 << PG_GLOBAL_BIT) | ||
| 146 | + | ||
| 147 | +#define PG_ERROR_W_BIT 1 | ||
| 148 | + | ||
| 149 | +#define PG_ERROR_P_MASK 0x01 | ||
| 150 | +#define PG_ERROR_W_MASK (1 << PG_ERROR_W_BIT) | ||
| 151 | +#define PG_ERROR_U_MASK 0x04 | ||
| 152 | +#define PG_ERROR_RSVD_MASK 0x08 | ||
| 153 | + | ||
| 154 | +#define MSR_IA32_APICBASE 0x1b | ||
| 155 | +#define MSR_IA32_APICBASE_BSP (1<<8) | ||
| 156 | +#define MSR_IA32_APICBASE_ENABLE (1<<11) | ||
| 157 | +#define MSR_IA32_APICBASE_BASE (0xfffff<<12) | ||
| 158 | + | ||
| 159 | +#define MSR_IA32_SYSENTER_CS 0x174 | ||
| 160 | +#define MSR_IA32_SYSENTER_ESP 0x175 | ||
| 161 | +#define MSR_IA32_SYSENTER_EIP 0x176 | ||
| 162 | + | ||
| 163 | +#define EXCP00_DIVZ 0 | ||
| 164 | +#define EXCP01_SSTP 1 | ||
| 165 | +#define EXCP02_NMI 2 | ||
| 166 | +#define EXCP03_INT3 3 | ||
| 167 | +#define EXCP04_INTO 4 | ||
| 168 | +#define EXCP05_BOUND 5 | ||
| 169 | +#define EXCP06_ILLOP 6 | ||
| 170 | +#define EXCP07_PREX 7 | ||
| 171 | +#define EXCP08_DBLE 8 | ||
| 172 | +#define EXCP09_XERR 9 | ||
| 173 | +#define EXCP0A_TSS 10 | ||
| 174 | +#define EXCP0B_NOSEG 11 | ||
| 175 | +#define EXCP0C_STACK 12 | ||
| 176 | +#define EXCP0D_GPF 13 | ||
| 177 | +#define EXCP0E_PAGE 14 | ||
| 178 | +#define EXCP10_COPR 16 | ||
| 179 | +#define EXCP11_ALGN 17 | ||
| 180 | +#define EXCP12_MCHK 18 | ||
| 181 | + | ||
| 182 | +enum { | ||
| 183 | + CC_OP_DYNAMIC, /* must use dynamic code to get cc_op */ | ||
| 184 | + CC_OP_EFLAGS, /* all cc are explicitely computed, CC_SRC = flags */ | ||
| 185 | + CC_OP_MUL, /* modify all flags, C, O = (CC_SRC != 0) */ | ||
| 186 | + | ||
| 187 | + CC_OP_ADDB, /* modify all flags, CC_DST = res, CC_SRC = src1 */ | ||
| 188 | + CC_OP_ADDW, | ||
| 189 | + CC_OP_ADDL, | ||
| 190 | + | ||
| 191 | + CC_OP_ADCB, /* modify all flags, CC_DST = res, CC_SRC = src1 */ | ||
| 192 | + CC_OP_ADCW, | ||
| 193 | + CC_OP_ADCL, | ||
| 194 | + | ||
| 195 | + CC_OP_SUBB, /* modify all flags, CC_DST = res, CC_SRC = src1 */ | ||
| 196 | + CC_OP_SUBW, | ||
| 197 | + CC_OP_SUBL, | ||
| 198 | + | ||
| 199 | + CC_OP_SBBB, /* modify all flags, CC_DST = res, CC_SRC = src1 */ | ||
| 200 | + CC_OP_SBBW, | ||
| 201 | + CC_OP_SBBL, | ||
| 202 | + | ||
| 203 | + CC_OP_LOGICB, /* modify all flags, CC_DST = res */ | ||
| 204 | + CC_OP_LOGICW, | ||
| 205 | + CC_OP_LOGICL, | ||
| 206 | + | ||
| 207 | + CC_OP_INCB, /* modify all flags except, CC_DST = res, CC_SRC = C */ | ||
| 208 | + CC_OP_INCW, | ||
| 209 | + CC_OP_INCL, | ||
| 210 | + | ||
| 211 | + CC_OP_DECB, /* modify all flags except, CC_DST = res, CC_SRC = C */ | ||
| 212 | + CC_OP_DECW, | ||
| 213 | + CC_OP_DECL, | ||
| 214 | + | ||
| 215 | + CC_OP_SHLB, /* modify all flags, CC_DST = res, CC_SRC.lsb = C */ | ||
| 216 | + CC_OP_SHLW, | ||
| 217 | + CC_OP_SHLL, | ||
| 218 | + | ||
| 219 | + CC_OP_SARB, /* modify all flags, CC_DST = res, CC_SRC.lsb = C */ | ||
| 220 | + CC_OP_SARW, | ||
| 221 | + CC_OP_SARL, | ||
| 222 | + | ||
| 223 | + CC_OP_NB, | ||
| 224 | +}; | ||
| 225 | + | ||
| 226 | +#ifdef __i386__ | ||
| 227 | +#define USE_X86LDOUBLE | ||
| 228 | +#endif | ||
| 229 | + | ||
| 230 | +#ifdef USE_X86LDOUBLE | ||
| 231 | +typedef long double CPU86_LDouble; | ||
| 232 | +#else | ||
| 233 | +typedef double CPU86_LDouble; | ||
| 234 | +#endif | ||
| 235 | + | ||
| 236 | +typedef struct SegmentCache { | ||
| 237 | + uint32_t selector; | ||
| 238 | + uint8_t *base; | ||
| 239 | + uint32_t limit; | ||
| 240 | + uint32_t flags; | ||
| 241 | +} SegmentCache; | ||
| 242 | + | ||
| 243 | +typedef struct CPUX86State { | ||
| 244 | + /* standard registers */ | ||
| 245 | + uint32_t regs[8]; | ||
| 246 | + uint32_t eip; | ||
| 247 | + uint32_t eflags; /* eflags register. During CPU emulation, CC | ||
| 248 | + flags and DF are set to zero because they are | ||
| 249 | + stored elsewhere */ | ||
| 250 | + | ||
| 251 | + /* emulator internal eflags handling */ | ||
| 252 | + uint32_t cc_src; | ||
| 253 | + uint32_t cc_dst; | ||
| 254 | + uint32_t cc_op; | ||
| 255 | + int32_t df; /* D flag : 1 if D = 0, -1 if D = 1 */ | ||
| 256 | + uint32_t hflags; /* hidden flags, see HF_xxx constants */ | ||
| 257 | + | ||
| 258 | + /* FPU state */ | ||
| 259 | + unsigned int fpstt; /* top of stack index */ | ||
| 260 | + unsigned int fpus; | ||
| 261 | + unsigned int fpuc; | ||
| 262 | + uint8_t fptags[8]; /* 0 = valid, 1 = empty */ | ||
| 263 | + CPU86_LDouble fpregs[8]; | ||
| 264 | + | ||
| 265 | + /* emulator internal variables */ | ||
| 266 | + CPU86_LDouble ft0; | ||
| 267 | + union { | ||
| 268 | + float f; | ||
| 269 | + double d; | ||
| 270 | + int i32; | ||
| 271 | + int64_t i64; | ||
| 272 | + } fp_convert; | ||
| 273 | + | ||
| 274 | + /* segments */ | ||
| 275 | + SegmentCache segs[6]; /* selector values */ | ||
| 276 | + SegmentCache ldt; | ||
| 277 | + SegmentCache tr; | ||
| 278 | + SegmentCache gdt; /* only base and limit are used */ | ||
| 279 | + SegmentCache idt; /* only base and limit are used */ | ||
| 280 | + | ||
| 281 | + /* sysenter registers */ | ||
| 282 | + uint32_t sysenter_cs; | ||
| 283 | + uint32_t sysenter_esp; | ||
| 284 | + uint32_t sysenter_eip; | ||
| 285 | + | ||
| 286 | + /* exception/interrupt handling */ | ||
| 287 | + jmp_buf jmp_env; | ||
| 288 | + int exception_index; | ||
| 289 | + int error_code; | ||
| 290 | + int exception_is_int; | ||
| 291 | + int exception_next_eip; | ||
| 292 | + struct TranslationBlock *current_tb; /* currently executing TB */ | ||
| 293 | + uint32_t cr[5]; /* NOTE: cr1 is unused */ | ||
| 294 | + uint32_t dr[8]; /* debug registers */ | ||
| 295 | + int interrupt_request; | ||
| 296 | + int user_mode_only; /* user mode only simulation */ | ||
| 297 | + | ||
| 298 | + /* soft mmu support */ | ||
| 299 | + /* 0 = kernel, 1 = user */ | ||
| 300 | + CPUTLBEntry tlb_read[2][CPU_TLB_SIZE]; | ||
| 301 | + CPUTLBEntry tlb_write[2][CPU_TLB_SIZE]; | ||
| 302 | + | ||
| 303 | + /* ice debug support */ | ||
| 304 | + uint32_t breakpoints[MAX_BREAKPOINTS]; | ||
| 305 | + int nb_breakpoints; | ||
| 306 | + int singlestep_enabled; | ||
| 307 | + | ||
| 308 | + /* user data */ | ||
| 309 | + void *opaque; | ||
| 310 | +} CPUX86State; | ||
| 311 | + | ||
| 312 | +#ifndef IN_OP_I386 | ||
| 313 | +void cpu_x86_outb(CPUX86State *env, int addr, int val); | ||
| 314 | +void cpu_x86_outw(CPUX86State *env, int addr, int val); | ||
| 315 | +void cpu_x86_outl(CPUX86State *env, int addr, int val); | ||
| 316 | +int cpu_x86_inb(CPUX86State *env, int addr); | ||
| 317 | +int cpu_x86_inw(CPUX86State *env, int addr); | ||
| 318 | +int cpu_x86_inl(CPUX86State *env, int addr); | ||
| 319 | +#endif | ||
| 320 | + | ||
| 321 | +CPUX86State *cpu_x86_init(void); | ||
| 322 | +int cpu_x86_exec(CPUX86State *s); | ||
| 323 | +void cpu_x86_close(CPUX86State *s); | ||
| 324 | +int cpu_x86_get_pic_interrupt(CPUX86State *s); | ||
| 325 | + | ||
| 326 | +/* this function must always be used to load data in the segment | ||
| 327 | + cache: it synchronizes the hflags with the segment cache values */ | ||
| 328 | +static inline void cpu_x86_load_seg_cache(CPUX86State *env, | ||
| 329 | + int seg_reg, unsigned int selector, | ||
| 330 | + uint8_t *base, unsigned int limit, | ||
| 331 | + unsigned int flags) | ||
| 332 | +{ | ||
| 333 | + SegmentCache *sc; | ||
| 334 | + unsigned int new_hflags; | ||
| 335 | + | ||
| 336 | + sc = &env->segs[seg_reg]; | ||
| 337 | + sc->selector = selector; | ||
| 338 | + sc->base = base; | ||
| 339 | + sc->limit = limit; | ||
| 340 | + sc->flags = flags; | ||
| 341 | + | ||
| 342 | + /* update the hidden flags */ | ||
| 343 | + new_hflags = (env->segs[R_CS].flags & DESC_B_MASK) | ||
| 344 | + >> (DESC_B_SHIFT - HF_CS32_SHIFT); | ||
| 345 | + new_hflags |= (env->segs[R_SS].flags & DESC_B_MASK) | ||
| 346 | + >> (DESC_B_SHIFT - HF_SS32_SHIFT); | ||
| 347 | + if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK)) { | ||
| 348 | + /* XXX: try to avoid this test. The problem comes from the | ||
| 349 | + fact that is real mode or vm86 mode we only modify the | ||
| 350 | + 'base' and 'selector' fields of the segment cache to go | ||
| 351 | + faster. A solution may be to force addseg to one in | ||
| 352 | + translate-i386.c. */ | ||
| 353 | + new_hflags |= HF_ADDSEG_MASK; | ||
| 354 | + } else { | ||
| 355 | + new_hflags |= (((unsigned long)env->segs[R_DS].base | | ||
| 356 | + (unsigned long)env->segs[R_ES].base | | ||
| 357 | + (unsigned long)env->segs[R_SS].base) != 0) << | ||
| 358 | + HF_ADDSEG_SHIFT; | ||
| 359 | + } | ||
| 360 | + env->hflags = (env->hflags & | ||
| 361 | + ~(HF_CS32_MASK | HF_SS32_MASK | HF_ADDSEG_MASK)) | new_hflags; | ||
| 362 | +} | ||
| 363 | + | ||
| 364 | +/* wrapper, just in case memory mappings must be changed */ | ||
| 365 | +static inline void cpu_x86_set_cpl(CPUX86State *s, int cpl) | ||
| 366 | +{ | ||
| 367 | +#if HF_CPL_MASK == 3 | ||
| 368 | + s->hflags = (s->hflags & ~HF_CPL_MASK) | cpl; | ||
| 369 | +#else | ||
| 370 | +#error HF_CPL_MASK is hardcoded | ||
| 371 | +#endif | ||
| 372 | +} | ||
| 373 | + | ||
| 374 | +/* the following helpers are only usable in user mode simulation as | ||
| 375 | + they can trigger unexpected exceptions */ | ||
| 376 | +void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector); | ||
| 377 | +void cpu_x86_fsave(CPUX86State *s, uint8_t *ptr, int data32); | ||
| 378 | +void cpu_x86_frstor(CPUX86State *s, uint8_t *ptr, int data32); | ||
| 379 | + | ||
| 380 | +/* you can call this signal handler from your SIGBUS and SIGSEGV | ||
| 381 | + signal handlers to inform the virtual CPU of exceptions. non zero | ||
| 382 | + is returned if the signal was handled by the virtual CPU. */ | ||
| 383 | +struct siginfo; | ||
| 384 | +int cpu_x86_signal_handler(int host_signum, struct siginfo *info, | ||
| 385 | + void *puc); | ||
| 386 | + | ||
| 387 | +/* MMU defines */ | ||
| 388 | +void cpu_x86_init_mmu(CPUX86State *env); | ||
| 389 | +extern int phys_ram_size; | ||
| 390 | +extern int phys_ram_fd; | ||
| 391 | +extern uint8_t *phys_ram_base; | ||
| 392 | + | ||
| 393 | +/* used to debug */ | ||
| 394 | +#define X86_DUMP_FPU 0x0001 /* dump FPU state too */ | ||
| 395 | +#define X86_DUMP_CCOP 0x0002 /* dump qemu flag cache */ | ||
| 396 | +void cpu_x86_dump_state(CPUX86State *env, FILE *f, int flags); | ||
| 397 | + | ||
| 398 | +#define TARGET_PAGE_BITS 12 | ||
| 399 | +#include "cpu-all.h" | ||
| 400 | + | ||
| 401 | +#endif /* CPU_I386_H */ |
target-i386/exec.h
0 → 100644
| 1 | +/* | ||
| 2 | + * i386 execution defines | ||
| 3 | + * | ||
| 4 | + * Copyright (c) 2003 Fabrice Bellard | ||
| 5 | + * | ||
| 6 | + * This library is free software; you can redistribute it and/or | ||
| 7 | + * modify it under the terms of the GNU Lesser General Public | ||
| 8 | + * License as published by the Free Software Foundation; either | ||
| 9 | + * version 2 of the License, or (at your option) any later version. | ||
| 10 | + * | ||
| 11 | + * This library is distributed in the hope that it will be useful, | ||
| 12 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 14 | + * Lesser General Public License for more details. | ||
| 15 | + * | ||
| 16 | + * You should have received a copy of the GNU Lesser General Public | ||
| 17 | + * License along with this library; if not, write to the Free Software | ||
| 18 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 19 | + */ | ||
| 20 | +#include "dyngen-exec.h" | ||
| 21 | + | ||
| 22 | +/* at least 4 register variables are defines */ | ||
| 23 | +register struct CPUX86State *env asm(AREG0); | ||
| 24 | +register uint32_t T0 asm(AREG1); | ||
| 25 | +register uint32_t T1 asm(AREG2); | ||
| 26 | +register uint32_t T2 asm(AREG3); | ||
| 27 | + | ||
| 28 | +#define A0 T2 | ||
| 29 | + | ||
| 30 | +/* if more registers are available, we define some registers too */ | ||
| 31 | +#ifdef AREG4 | ||
| 32 | +register uint32_t EAX asm(AREG4); | ||
| 33 | +#define reg_EAX | ||
| 34 | +#endif | ||
| 35 | + | ||
| 36 | +#ifdef AREG5 | ||
| 37 | +register uint32_t ESP asm(AREG5); | ||
| 38 | +#define reg_ESP | ||
| 39 | +#endif | ||
| 40 | + | ||
| 41 | +#ifdef AREG6 | ||
| 42 | +register uint32_t EBP asm(AREG6); | ||
| 43 | +#define reg_EBP | ||
| 44 | +#endif | ||
| 45 | + | ||
| 46 | +#ifdef AREG7 | ||
| 47 | +register uint32_t ECX asm(AREG7); | ||
| 48 | +#define reg_ECX | ||
| 49 | +#endif | ||
| 50 | + | ||
| 51 | +#ifdef AREG8 | ||
| 52 | +register uint32_t EDX asm(AREG8); | ||
| 53 | +#define reg_EDX | ||
| 54 | +#endif | ||
| 55 | + | ||
| 56 | +#ifdef AREG9 | ||
| 57 | +register uint32_t EBX asm(AREG9); | ||
| 58 | +#define reg_EBX | ||
| 59 | +#endif | ||
| 60 | + | ||
| 61 | +#ifdef AREG10 | ||
| 62 | +register uint32_t ESI asm(AREG10); | ||
| 63 | +#define reg_ESI | ||
| 64 | +#endif | ||
| 65 | + | ||
| 66 | +#ifdef AREG11 | ||
| 67 | +register uint32_t EDI asm(AREG11); | ||
| 68 | +#define reg_EDI | ||
| 69 | +#endif | ||
| 70 | + | ||
| 71 | +extern FILE *logfile; | ||
| 72 | +extern int loglevel; | ||
| 73 | + | ||
| 74 | +#ifndef reg_EAX | ||
| 75 | +#define EAX (env->regs[R_EAX]) | ||
| 76 | +#endif | ||
| 77 | +#ifndef reg_ECX | ||
| 78 | +#define ECX (env->regs[R_ECX]) | ||
| 79 | +#endif | ||
| 80 | +#ifndef reg_EDX | ||
| 81 | +#define EDX (env->regs[R_EDX]) | ||
| 82 | +#endif | ||
| 83 | +#ifndef reg_EBX | ||
| 84 | +#define EBX (env->regs[R_EBX]) | ||
| 85 | +#endif | ||
| 86 | +#ifndef reg_ESP | ||
| 87 | +#define ESP (env->regs[R_ESP]) | ||
| 88 | +#endif | ||
| 89 | +#ifndef reg_EBP | ||
| 90 | +#define EBP (env->regs[R_EBP]) | ||
| 91 | +#endif | ||
| 92 | +#ifndef reg_ESI | ||
| 93 | +#define ESI (env->regs[R_ESI]) | ||
| 94 | +#endif | ||
| 95 | +#ifndef reg_EDI | ||
| 96 | +#define EDI (env->regs[R_EDI]) | ||
| 97 | +#endif | ||
| 98 | +#define EIP (env->eip) | ||
| 99 | +#define DF (env->df) | ||
| 100 | + | ||
| 101 | +#define CC_SRC (env->cc_src) | ||
| 102 | +#define CC_DST (env->cc_dst) | ||
| 103 | +#define CC_OP (env->cc_op) | ||
| 104 | + | ||
| 105 | +/* float macros */ | ||
| 106 | +#define FT0 (env->ft0) | ||
| 107 | +#define ST0 (env->fpregs[env->fpstt]) | ||
| 108 | +#define ST(n) (env->fpregs[(env->fpstt + (n)) & 7]) | ||
| 109 | +#define ST1 ST(1) | ||
| 110 | + | ||
| 111 | +#ifdef USE_FP_CONVERT | ||
| 112 | +#define FP_CONVERT (env->fp_convert) | ||
| 113 | +#endif | ||
| 114 | + | ||
| 115 | +#include "cpu.h" | ||
| 116 | +#include "exec-all.h" | ||
| 117 | + | ||
| 118 | +typedef struct CCTable { | ||
| 119 | + int (*compute_all)(void); /* return all the flags */ | ||
| 120 | + int (*compute_c)(void); /* return the C flag */ | ||
| 121 | +} CCTable; | ||
| 122 | + | ||
| 123 | +extern CCTable cc_table[]; | ||
| 124 | + | ||
| 125 | +void load_seg(int seg_reg, int selector, unsigned cur_eip); | ||
| 126 | +void helper_ljmp_protected_T0_T1(void); | ||
| 127 | +void helper_lcall_real_T0_T1(int shift, int next_eip); | ||
| 128 | +void helper_lcall_protected_T0_T1(int shift, int next_eip); | ||
| 129 | +void helper_iret_real(int shift); | ||
| 130 | +void helper_iret_protected(int shift); | ||
| 131 | +void helper_lret_protected(int shift, int addend); | ||
| 132 | +void helper_lldt_T0(void); | ||
| 133 | +void helper_ltr_T0(void); | ||
| 134 | +void helper_movl_crN_T0(int reg); | ||
| 135 | +void helper_movl_drN_T0(int reg); | ||
| 136 | +void helper_invlpg(unsigned int addr); | ||
| 137 | +void cpu_x86_update_cr0(CPUX86State *env); | ||
| 138 | +void cpu_x86_update_cr3(CPUX86State *env); | ||
| 139 | +void cpu_x86_flush_tlb(CPUX86State *env, uint32_t addr); | ||
| 140 | +int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, int is_write); | ||
| 141 | +void tlb_fill(unsigned long addr, int is_write, void *retaddr); | ||
| 142 | +void __hidden cpu_lock(void); | ||
| 143 | +void __hidden cpu_unlock(void); | ||
| 144 | +void do_interrupt(int intno, int is_int, int error_code, | ||
| 145 | + unsigned int next_eip, int is_hw); | ||
| 146 | +void do_interrupt_user(int intno, int is_int, int error_code, | ||
| 147 | + unsigned int next_eip); | ||
| 148 | +void raise_interrupt(int intno, int is_int, int error_code, | ||
| 149 | + unsigned int next_eip); | ||
| 150 | +void raise_exception_err(int exception_index, int error_code); | ||
| 151 | +void raise_exception(int exception_index); | ||
| 152 | +void __hidden cpu_loop_exit(void); | ||
| 153 | +void helper_fsave(uint8_t *ptr, int data32); | ||
| 154 | +void helper_frstor(uint8_t *ptr, int data32); | ||
| 155 | + | ||
| 156 | +void OPPROTO op_movl_eflags_T0(void); | ||
| 157 | +void OPPROTO op_movl_T0_eflags(void); | ||
| 158 | +void raise_interrupt(int intno, int is_int, int error_code, | ||
| 159 | + unsigned int next_eip); | ||
| 160 | +void raise_exception_err(int exception_index, int error_code); | ||
| 161 | +void raise_exception(int exception_index); | ||
| 162 | +void helper_divl_EAX_T0(uint32_t eip); | ||
| 163 | +void helper_idivl_EAX_T0(uint32_t eip); | ||
| 164 | +void helper_cmpxchg8b(void); | ||
| 165 | +void helper_cpuid(void); | ||
| 166 | +void helper_rdtsc(void); | ||
| 167 | +void helper_rdmsr(void); | ||
| 168 | +void helper_wrmsr(void); | ||
| 169 | +void helper_lsl(void); | ||
| 170 | +void helper_lar(void); | ||
| 171 | + | ||
| 172 | +#ifdef USE_X86LDOUBLE | ||
| 173 | +/* use long double functions */ | ||
| 174 | +#define lrint lrintl | ||
| 175 | +#define llrint llrintl | ||
| 176 | +#define fabs fabsl | ||
| 177 | +#define sin sinl | ||
| 178 | +#define cos cosl | ||
| 179 | +#define sqrt sqrtl | ||
| 180 | +#define pow powl | ||
| 181 | +#define log logl | ||
| 182 | +#define tan tanl | ||
| 183 | +#define atan2 atan2l | ||
| 184 | +#define floor floorl | ||
| 185 | +#define ceil ceill | ||
| 186 | +#define rint rintl | ||
| 187 | +#endif | ||
| 188 | + | ||
| 189 | +extern int lrint(CPU86_LDouble x); | ||
| 190 | +extern int64_t llrint(CPU86_LDouble x); | ||
| 191 | +extern CPU86_LDouble fabs(CPU86_LDouble x); | ||
| 192 | +extern CPU86_LDouble sin(CPU86_LDouble x); | ||
| 193 | +extern CPU86_LDouble cos(CPU86_LDouble x); | ||
| 194 | +extern CPU86_LDouble sqrt(CPU86_LDouble x); | ||
| 195 | +extern CPU86_LDouble pow(CPU86_LDouble, CPU86_LDouble); | ||
| 196 | +extern CPU86_LDouble log(CPU86_LDouble x); | ||
| 197 | +extern CPU86_LDouble tan(CPU86_LDouble x); | ||
| 198 | +extern CPU86_LDouble atan2(CPU86_LDouble, CPU86_LDouble); | ||
| 199 | +extern CPU86_LDouble floor(CPU86_LDouble x); | ||
| 200 | +extern CPU86_LDouble ceil(CPU86_LDouble x); | ||
| 201 | +extern CPU86_LDouble rint(CPU86_LDouble x); | ||
| 202 | + | ||
| 203 | +#define RC_MASK 0xc00 | ||
| 204 | +#define RC_NEAR 0x000 | ||
| 205 | +#define RC_DOWN 0x400 | ||
| 206 | +#define RC_UP 0x800 | ||
| 207 | +#define RC_CHOP 0xc00 | ||
| 208 | + | ||
| 209 | +#define MAXTAN 9223372036854775808.0 | ||
| 210 | + | ||
| 211 | +#ifdef __arm__ | ||
| 212 | +/* we have no way to do correct rounding - a FPU emulator is needed */ | ||
| 213 | +#define FE_DOWNWARD FE_TONEAREST | ||
| 214 | +#define FE_UPWARD FE_TONEAREST | ||
| 215 | +#define FE_TOWARDZERO FE_TONEAREST | ||
| 216 | +#endif | ||
| 217 | + | ||
| 218 | +#ifdef USE_X86LDOUBLE | ||
| 219 | + | ||
| 220 | +/* only for x86 */ | ||
| 221 | +typedef union { | ||
| 222 | + long double d; | ||
| 223 | + struct { | ||
| 224 | + unsigned long long lower; | ||
| 225 | + unsigned short upper; | ||
| 226 | + } l; | ||
| 227 | +} CPU86_LDoubleU; | ||
| 228 | + | ||
| 229 | +/* the following deal with x86 long double-precision numbers */ | ||
| 230 | +#define MAXEXPD 0x7fff | ||
| 231 | +#define EXPBIAS 16383 | ||
| 232 | +#define EXPD(fp) (fp.l.upper & 0x7fff) | ||
| 233 | +#define SIGND(fp) ((fp.l.upper) & 0x8000) | ||
| 234 | +#define MANTD(fp) (fp.l.lower) | ||
| 235 | +#define BIASEXPONENT(fp) fp.l.upper = (fp.l.upper & ~(0x7fff)) | EXPBIAS | ||
| 236 | + | ||
| 237 | +#else | ||
| 238 | + | ||
| 239 | +/* NOTE: arm is horrible as double 32 bit words are stored in big endian ! */ | ||
| 240 | +typedef union { | ||
| 241 | + double d; | ||
| 242 | +#if !defined(WORDS_BIGENDIAN) && !defined(__arm__) | ||
| 243 | + struct { | ||
| 244 | + uint32_t lower; | ||
| 245 | + int32_t upper; | ||
| 246 | + } l; | ||
| 247 | +#else | ||
| 248 | + struct { | ||
| 249 | + int32_t upper; | ||
| 250 | + uint32_t lower; | ||
| 251 | + } l; | ||
| 252 | +#endif | ||
| 253 | +#ifndef __arm__ | ||
| 254 | + int64_t ll; | ||
| 255 | +#endif | ||
| 256 | +} CPU86_LDoubleU; | ||
| 257 | + | ||
| 258 | +/* the following deal with IEEE double-precision numbers */ | ||
| 259 | +#define MAXEXPD 0x7ff | ||
| 260 | +#define EXPBIAS 1023 | ||
| 261 | +#define EXPD(fp) (((fp.l.upper) >> 20) & 0x7FF) | ||
| 262 | +#define SIGND(fp) ((fp.l.upper) & 0x80000000) | ||
| 263 | +#ifdef __arm__ | ||
| 264 | +#define MANTD(fp) (fp.l.lower | ((uint64_t)(fp.l.upper & ((1 << 20) - 1)) << 32)) | ||
| 265 | +#else | ||
| 266 | +#define MANTD(fp) (fp.ll & ((1LL << 52) - 1)) | ||
| 267 | +#endif | ||
| 268 | +#define BIASEXPONENT(fp) fp.l.upper = (fp.l.upper & ~(0x7ff << 20)) | (EXPBIAS << 20) | ||
| 269 | +#endif | ||
| 270 | + | ||
| 271 | +static inline void fpush(void) | ||
| 272 | +{ | ||
| 273 | + env->fpstt = (env->fpstt - 1) & 7; | ||
| 274 | + env->fptags[env->fpstt] = 0; /* validate stack entry */ | ||
| 275 | +} | ||
| 276 | + | ||
| 277 | +static inline void fpop(void) | ||
| 278 | +{ | ||
| 279 | + env->fptags[env->fpstt] = 1; /* invvalidate stack entry */ | ||
| 280 | + env->fpstt = (env->fpstt + 1) & 7; | ||
| 281 | +} | ||
| 282 | + | ||
| 283 | +#ifndef USE_X86LDOUBLE | ||
| 284 | +static inline CPU86_LDouble helper_fldt(uint8_t *ptr) | ||
| 285 | +{ | ||
| 286 | + CPU86_LDoubleU temp; | ||
| 287 | + int upper, e; | ||
| 288 | + uint64_t ll; | ||
| 289 | + | ||
| 290 | + /* mantissa */ | ||
| 291 | + upper = lduw(ptr + 8); | ||
| 292 | + /* XXX: handle overflow ? */ | ||
| 293 | + e = (upper & 0x7fff) - 16383 + EXPBIAS; /* exponent */ | ||
| 294 | + e |= (upper >> 4) & 0x800; /* sign */ | ||
| 295 | + ll = (ldq(ptr) >> 11) & ((1LL << 52) - 1); | ||
| 296 | +#ifdef __arm__ | ||
| 297 | + temp.l.upper = (e << 20) | (ll >> 32); | ||
| 298 | + temp.l.lower = ll; | ||
| 299 | +#else | ||
| 300 | + temp.ll = ll | ((uint64_t)e << 52); | ||
| 301 | +#endif | ||
| 302 | + return temp.d; | ||
| 303 | +} | ||
| 304 | + | ||
| 305 | +static inline void helper_fstt(CPU86_LDouble f, uint8_t *ptr) | ||
| 306 | +{ | ||
| 307 | + CPU86_LDoubleU temp; | ||
| 308 | + int e; | ||
| 309 | + | ||
| 310 | + temp.d = f; | ||
| 311 | + /* mantissa */ | ||
| 312 | + stq(ptr, (MANTD(temp) << 11) | (1LL << 63)); | ||
| 313 | + /* exponent + sign */ | ||
| 314 | + e = EXPD(temp) - EXPBIAS + 16383; | ||
| 315 | + e |= SIGND(temp) >> 16; | ||
| 316 | + stw(ptr + 8, e); | ||
| 317 | +} | ||
| 318 | +#endif | ||
| 319 | + | ||
| 320 | +const CPU86_LDouble f15rk[7]; | ||
| 321 | + | ||
| 322 | +void helper_fldt_ST0_A0(void); | ||
| 323 | +void helper_fstt_ST0_A0(void); | ||
| 324 | +void helper_fbld_ST0_A0(void); | ||
| 325 | +void helper_fbst_ST0_A0(void); | ||
| 326 | +void helper_f2xm1(void); | ||
| 327 | +void helper_fyl2x(void); | ||
| 328 | +void helper_fptan(void); | ||
| 329 | +void helper_fpatan(void); | ||
| 330 | +void helper_fxtract(void); | ||
| 331 | +void helper_fprem1(void); | ||
| 332 | +void helper_fprem(void); | ||
| 333 | +void helper_fyl2xp1(void); | ||
| 334 | +void helper_fsqrt(void); | ||
| 335 | +void helper_fsincos(void); | ||
| 336 | +void helper_frndint(void); | ||
| 337 | +void helper_fscale(void); | ||
| 338 | +void helper_fsin(void); | ||
| 339 | +void helper_fcos(void); | ||
| 340 | +void helper_fxam_ST0(void); | ||
| 341 | +void helper_fstenv(uint8_t *ptr, int data32); | ||
| 342 | +void helper_fldenv(uint8_t *ptr, int data32); | ||
| 343 | +void helper_fsave(uint8_t *ptr, int data32); | ||
| 344 | +void helper_frstor(uint8_t *ptr, int data32); | ||
| 345 | + | ||
| 346 | +const uint8_t parity_table[256]; | ||
| 347 | +const uint8_t rclw_table[32]; | ||
| 348 | +const uint8_t rclb_table[32]; | ||
| 349 | + | ||
| 350 | +static inline uint32_t compute_eflags(void) | ||
| 351 | +{ | ||
| 352 | + return env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK); | ||
| 353 | +} | ||
| 354 | + | ||
| 355 | +#define FL_UPDATE_MASK32 (TF_MASK | AC_MASK | ID_MASK) | ||
| 356 | + | ||
| 357 | +#define FL_UPDATE_CPL0_MASK (TF_MASK | IF_MASK | IOPL_MASK | NT_MASK | \ | ||
| 358 | + RF_MASK | AC_MASK | ID_MASK) | ||
| 359 | + | ||
| 360 | +/* NOTE: CC_OP must be modified manually to CC_OP_EFLAGS */ | ||
| 361 | +static inline void load_eflags(int eflags, int update_mask) | ||
| 362 | +{ | ||
| 363 | + CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); | ||
| 364 | + DF = 1 - (2 * ((eflags >> 10) & 1)); | ||
| 365 | + env->eflags = (env->eflags & ~update_mask) | | ||
| 366 | + (eflags & update_mask); | ||
| 367 | +} | ||
| 368 | + | ||
| 369 | +/* memory access macros */ | ||
| 370 | + | ||
| 371 | +#define ldul ldl | ||
| 372 | +#define lduq ldq | ||
| 373 | +#define ldul_user ldl_user | ||
| 374 | +#define ldul_kernel ldl_kernel | ||
| 375 | + | ||
| 376 | +#define ldub_raw ldub | ||
| 377 | +#define ldsb_raw ldsb | ||
| 378 | +#define lduw_raw lduw | ||
| 379 | +#define ldsw_raw ldsw | ||
| 380 | +#define ldl_raw ldl | ||
| 381 | +#define ldq_raw ldq | ||
| 382 | + | ||
| 383 | +#define stb_raw stb | ||
| 384 | +#define stw_raw stw | ||
| 385 | +#define stl_raw stl | ||
| 386 | +#define stq_raw stq | ||
| 387 | + | ||
| 388 | +#define MEMUSER 0 | ||
| 389 | +#define DATA_SIZE 1 | ||
| 390 | +#include "softmmu_header.h" | ||
| 391 | + | ||
| 392 | +#define DATA_SIZE 2 | ||
| 393 | +#include "softmmu_header.h" | ||
| 394 | + | ||
| 395 | +#define DATA_SIZE 4 | ||
| 396 | +#include "softmmu_header.h" | ||
| 397 | + | ||
| 398 | +#define DATA_SIZE 8 | ||
| 399 | +#include "softmmu_header.h" | ||
| 400 | + | ||
| 401 | +#undef MEMUSER | ||
| 402 | +#define MEMUSER 1 | ||
| 403 | +#define DATA_SIZE 1 | ||
| 404 | +#include "softmmu_header.h" | ||
| 405 | + | ||
| 406 | +#define DATA_SIZE 2 | ||
| 407 | +#include "softmmu_header.h" | ||
| 408 | + | ||
| 409 | +#define DATA_SIZE 4 | ||
| 410 | +#include "softmmu_header.h" | ||
| 411 | + | ||
| 412 | +#define DATA_SIZE 8 | ||
| 413 | +#include "softmmu_header.h" | ||
| 414 | + | ||
| 415 | +#undef MEMUSER | ||
| 416 | + |