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 | + | ... | ... |