2 * This file is part of the Palacios Virtual Machine Monitor developed
3 * by the V3VEE Project with funding from the United States National
4 * Science Foundation and the Department of Energy.
6 * The V3VEE Project is a joint project between Northwestern University
7 * and the University of New Mexico. You can find out more at
10 * Copyright (c) 2012, Alexander Kudryavtsev <alexk@ispras.ru>
11 * Copyright (c) 2012, The V3VEE Project <http://www.v3vee.org>
12 * All rights reserved.
14 * Author: Alexander Kudryavtsev <alexk@ispras.ru>
16 * This is free software. You are permitted to use,
17 * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
20 #include <palacios/vmm.h>
21 #include <palacios/vm_guest.h>
22 #include <palacios/vmm_mem_hook.h>
23 #include <palacios/vmm_emulator.h>
24 #include <palacios/vm_guest_mem.h>
25 #include <palacios/vmm_hashtable.h>
26 #include <palacios/vmm_decoder.h>
28 #include <quix86/quix86.h>
30 #ifndef V3_CONFIG_DEBUG_DECODER
32 #define PrintDebug(fmt, args...)
35 #define GPR_REGISTER 0
36 #define SEGMENT_REGISTER 1
37 #define CTRL_REGISTER 2
38 #define DEBUG_REGISTER 3
40 // QUIX86 does not have to be initialised or deinitialised.
41 int v3_init_decoder(struct guest_info * core) {
44 int v3_deinit_decoder(struct guest_info * core) {
48 static int get_opcode(qx86_insn *inst);
49 static int qx86_register_to_v3_reg(struct guest_info * info, int qx86_reg,
50 addr_t * v3_reg, uint_t * reg_len);
52 static int decode_string_op(struct guest_info * core,
53 const qx86_insn * qx86_inst, struct x86_instr * instr)
56 PrintDebug("String operation\n");
58 if (instr->prefixes.rep == 1) {
59 uint64_t a_mask = ~(~0ULL <<
60 (QX86_SIZE_OCTETS(qx86_inst->attributes.addressSize) * 8));
62 instr->str_op_length = core->vm_regs.rcx & a_mask;
64 instr->str_op_length = 1;
69 if (instr->op_type == V3_OP_MOVS) {
70 instr->num_operands = 2;
72 if((status = qx86_calculate_linear_address(qx86_inst, 0,
73 (qx86_uint64*)&instr->dst_operand.operand)) != QX86_SUCCESS) {
74 PrintError("Could not get destination memory operand: "
75 "qx86_calculate_linear_address: %d\n", status);
79 instr->dst_operand.type = MEM_OPERAND;
80 instr->dst_operand.size = qx86_inst->operands[0].size;
83 if((status = qx86_calculate_linear_address(qx86_inst, 1,
84 (qx86_uint64*)&instr->src_operand.operand)) != QX86_SUCCESS) {
85 PrintError("Could not get source memory operand: "
86 "qx86_calculate_linear_address: %d\n", status);
90 instr->src_operand.type = MEM_OPERAND;
91 instr->src_operand.size = qx86_inst->operands[1].size;
93 instr->dst_operand.write = 1;
94 instr->src_operand.read = 1;
97 } else if (instr->op_type == V3_OP_STOS) {
98 instr->num_operands = 2;
100 if((status = qx86_calculate_linear_address(qx86_inst, 0,
101 (qx86_uint64*)&instr->dst_operand.operand)) != QX86_SUCCESS) {
102 PrintError("Could not get destination memory operand: "
103 "qx86_calculate_linear_address: %d\n", status);
107 instr->dst_operand.type = MEM_OPERAND;
108 instr->dst_operand.size = qx86_inst->operands[0].size;
110 // STOS reads from rax
111 qx86_register_to_v3_reg(core,
112 qx86_inst->operands[1].u.r.rindex,
113 &(instr->src_operand.operand), &(instr->src_operand.size));
114 instr->src_operand.type = REG_OPERAND;
116 instr->src_operand.read = 1;
117 instr->dst_operand.write = 1;
122 PrintError("Unhandled String OP\n");
127 #ifdef V3_CONFIG_DEBUG_DECODER
128 V3_Print("Decoding Instr at %p\n", (void *)core->rip);
129 v3_print_instr(instr);
130 V3_Print("CS DB FLag=%x\n", core->segments.cs.db);
137 static int callback(void *data, int rindex, int subreg, unsigned char *value) {
141 struct guest_info *info = (struct guest_info*)data;
142 int v3_reg_type = qx86_register_to_v3_reg(info,
144 (addr_t*)®_addr, ®_size);
146 if(v3_reg_type == -1) {
147 PrintError("Callback failed to get register index %d\n", rindex);
151 *(uint64_t*)value = 0;
153 case QX86_SUBREG_BASE:
154 *(uint64_t*)value = ((struct v3_segment*)reg_addr)->base;
156 case QX86_SUBREG_LIMIT:
157 *(uint32_t*)value = ((struct v3_segment*)reg_addr)->limit;
159 case QX86_SUBREG_FLAGS:
160 PrintError("Callback doesn't know how to give flags.\n");
162 case QX86_SUBREG_NONE: {
163 switch(qx86_rtab[rindex].size) {
164 case 1: *(uint8_t* )value = *(uint8_t* )reg_addr; break;
165 case 2: *(uint16_t*)value = *(uint16_t*)reg_addr; break;
166 case 4: *(uint32_t*)value = *(uint32_t*)reg_addr; break;
167 case 8: *(uint64_t*)value = *(uint64_t*)reg_addr; break;
176 static inline int qx86_op_to_v3_op(struct guest_info *info, qx86_insn *qx86_insn,
177 int op_num, struct x86_operand * v3_op) {
179 qx86_operand *qx86_op = &qx86_insn->operands[op_num];
180 if (qx86_op->ot == QX86_OPERAND_TYPE_REGISTER) {
181 int v3_reg_type = qx86_register_to_v3_reg(info,
183 &(v3_op->operand), &(v3_op->size));
185 if (v3_reg_type == -1) {
186 PrintError("Operand %d is an Unhandled Operand: %s\n", op_num,
187 qx86_rtab[qx86_op->u.r.rindex].name);
188 v3_op->type = INVALID_OPERAND;
190 } else if (v3_reg_type == SEGMENT_REGISTER) {
191 struct v3_segment * seg_reg = (struct v3_segment *)(v3_op->operand);
192 v3_op->operand = (addr_t)&(seg_reg->selector);
194 v3_op->type = REG_OPERAND;
196 } else if(qx86_op->ot == QX86_OPERAND_TYPE_MEMORY) {
197 PrintDebug("Memory operand (%d)\n", op_num);
198 if((status = qx86_calculate_linear_address(qx86_insn, op_num,
199 (qx86_uint64*)&v3_op->operand)) != QX86_SUCCESS) {
200 PrintError("Could not get memory operand %d: "
201 "qx86_calculate_linear_address() returns %d\n", op_num, status);
204 v3_op->type = MEM_OPERAND;
205 v3_op->size = qx86_op->size;
207 } else if(qx86_op->ot == QX86_OPERAND_TYPE_IMMEDIATE) {
208 v3_op->size = qx86_op->u.i.valueSize;
210 if (v3_op->size > 4) {
211 PrintError("Unhandled 64 bit immediates\n");
214 v3_op->operand = (addr_t)*(uint64_t*)qx86_op->u.i.value;
215 v3_op->type = IMM_OPERAND;
218 PrintError("Unhandled Operand %d Type %d\n", op_num, qx86_op->ot);
222 if (qx86_op->attributes & QX86_OPERAND_ATTRIBUTE_READ) {
225 if (qx86_op->attributes & QX86_OPERAND_ATTRIBUTE_WRITTEN) {
231 int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * instr) {
234 uint8_t inst_buf[QX86_INSN_SIZE_MAX];
236 memset(instr, 0, sizeof(struct x86_instr));
237 memset(&qx86_inst, 0, sizeof(qx86_inst));
239 v3_get_prefixes((uchar_t *)instr_ptr, &(instr->prefixes));
241 switch(v3_get_vm_cpu_mode(info)) {
242 case REAL: case LONG_16_COMPAT:
243 proc_mode = QX86_SIZE_16; break;
244 case PROTECTED: case PROTECTED_PAE: case LONG_32_COMPAT:
245 proc_mode = QX86_SIZE_32; break;
247 proc_mode = QX86_SIZE_64; break;
249 PrintError("Unsupported CPU mode: %d\n", info->cpu_mode);
253 int left_in_page = 0x1000 - (instr_ptr & 0xfff);
254 if(left_in_page < QX86_INSN_SIZE_MAX) {
258 if (info->mem_mode == PHYSICAL_MEM) {
259 status = v3_gpa_to_hva(info, get_addr_linear(info,
260 (info->rip & ~0xfffULL) + 0x1000, &(info->segments.cs)), &instr_ptr2);
262 status = v3_gva_to_hva(info, get_addr_linear(info,
263 (info->rip & ~0xfffULL) + 0x1000, &(info->segments.cs)), &instr_ptr2);
266 PrintError("Could not translate Instruction Address at second stage "
267 "translation (%p)\n", (void *)(addr_t)info->rip);
271 if(((instr_ptr & ~0xfffUL) + 0x1000) != instr_ptr2) {
272 PrintError("Note: physical page non-contiguous\n");
273 memcpy(inst_buf, (const void*)instr_ptr, left_in_page);
274 memcpy(inst_buf + left_in_page, (const void*)instr_ptr2,
275 QX86_INSN_SIZE_MAX - left_in_page);
276 instr_ptr = (addr_t)inst_buf;
277 } // in other case, address space is contiguous and everything is OK
280 qx86_inst.callback = callback;
281 qx86_inst.data = info;
283 int status = qx86_decode(&qx86_inst, proc_mode,
284 (const void*)instr_ptr, QX86_INSN_SIZE_MAX);
285 if(status != QX86_SUCCESS) {
286 PrintError("qx86_decode() returned %d\n", status);
290 instr->instr_length = qx86_inst.rawSize;
292 if ((instr->op_type = get_opcode(&qx86_inst)) == V3_INVALID_OP) {
293 PrintError("Could not get opcode. (mnemonic=%s)\n",
294 qx86_mtab[qx86_inst.mnemonic].name);
298 if(instr->op_type == V3_OP_MOVS || instr->op_type == V3_OP_STOS) {
299 instr->is_str_op = 1;
300 return decode_string_op(info, &qx86_inst, instr);
302 instr->is_str_op = 0;
303 instr->str_op_length = 0;
306 instr->num_operands = qx86_inst.operandCount;
309 if (instr->num_operands >= 1) {
310 if (qx86_op_to_v3_op(info, &qx86_inst, 0, &instr->dst_operand) != 0)
314 // set second operand
315 if (instr->num_operands >= 2) {
316 if (qx86_op_to_v3_op(info, &qx86_inst, 1, &instr->src_operand) != 0)
321 if (instr->num_operands >= 3) {
322 if (qx86_op_to_v3_op(info, &qx86_inst, 2, &instr->third_operand) != 0)
326 #ifdef V3_CONFIG_DEBUG_DECODER
327 qx86_print_options_intel opt;
330 if(qx86_print_intel(&qx86_inst, &opt, buf, &buf_sz) != QX86_SUCCESS) {
331 PrintDebug("Print failed!\n");
333 PrintDebug("Instruction (%p): %s\n", (void*)info->rip, buf);
335 PrintDebug("Operands: dst %p src %p 3rd %p\n", (void*)instr->dst_operand.operand,
336 (void*)instr->src_operand.operand, (void*)instr->third_operand.operand);
341 static int get_opcode(qx86_insn *inst) {
342 switch (inst->mnemonic) {
343 #define IS_CR(op) inst->operands[op].ot == QX86_OPERAND_TYPE_REGISTER && \
344 qx86_rtab[inst->operands[op].u.r.rindex].rclass == QX86_RCLASS_CREG
347 case QX86_MNEMONIC_MOV: {
348 if(inst->operands[0].ot == QX86_OPERAND_TYPE_MEMORY
349 || inst->operands[1].ot == QX86_OPERAND_TYPE_MEMORY)
356 PrintError("Bad operand types for MOV: %d %d\n", inst->operands[0].ot,
357 inst->operands[1].ot);
358 return V3_INVALID_OP;
361 /* Control Instructions */
362 case QX86_MNEMONIC_SMSW:
365 case QX86_MNEMONIC_LMSW:
368 case QX86_MNEMONIC_CLTS:
371 case QX86_MNEMONIC_INVLPG:
374 /* Data Instructions */
375 case QX86_MNEMONIC_ADC:
378 case QX86_MNEMONIC_ADD:
381 case QX86_MNEMONIC_AND:
384 case QX86_MNEMONIC_SUB:
388 case QX86_MNEMONIC_MOVZX:
391 case QX86_MNEMONIC_MOVSX:
395 case QX86_MNEMONIC_DEC:
398 case QX86_MNEMONIC_INC:
401 case QX86_MNEMONIC_OR:
404 case QX86_MNEMONIC_XOR:
407 case QX86_MNEMONIC_NEG:
410 case QX86_MNEMONIC_NOT:
413 case QX86_MNEMONIC_XCHG:
416 case QX86_MNEMONIC_SETB:
419 case QX86_MNEMONIC_SETBE:
422 case QX86_MNEMONIC_SETL:
425 case QX86_MNEMONIC_SETLE:
428 case QX86_MNEMONIC_SETAE:
431 case QX86_MNEMONIC_SETA:
434 case QX86_MNEMONIC_SETGE:
437 case QX86_MNEMONIC_SETG:
440 case QX86_MNEMONIC_SETNO:
443 case QX86_MNEMONIC_SETNP:
446 case QX86_MNEMONIC_SETNS:
449 case QX86_MNEMONIC_SETNZ:
452 case QX86_MNEMONIC_SETO:
455 case QX86_MNEMONIC_SETP:
458 case QX86_MNEMONIC_SETS:
461 case QX86_MNEMONIC_SETZ:
464 case QX86_MNEMONIC_MOVSB:
465 case QX86_MNEMONIC_MOVSW:
466 case QX86_MNEMONIC_MOVSD:
467 case QX86_MNEMONIC_MOVSQ:
470 case QX86_MNEMONIC_STOSB:
471 case QX86_MNEMONIC_STOSW:
472 case QX86_MNEMONIC_STOSD:
473 case QX86_MNEMONIC_STOSQ:
478 return V3_INVALID_OP;
482 static int qx86_register_to_v3_reg(struct guest_info * info, int qx86_reg,
483 addr_t * v3_reg, uint_t * reg_len) {
484 PrintDebug("qx86 Register: %s\n", qx86_rtab[qx86_reg].name);
487 case QX86_REGISTER_INVALID:
492 case QX86_REGISTER_RAX:
493 *v3_reg = (addr_t)&(info->vm_regs.rax);
496 case QX86_REGISTER_EAX:
497 *v3_reg = (addr_t)&(info->vm_regs.rax);
500 case QX86_REGISTER_AX:
501 *v3_reg = (addr_t)&(info->vm_regs.rax);
504 case QX86_REGISTER_AH:
505 *v3_reg = (addr_t)(&(info->vm_regs.rax)) + 1;
508 case QX86_REGISTER_AL:
509 *v3_reg = (addr_t)&(info->vm_regs.rax);
513 case QX86_REGISTER_RCX:
514 *v3_reg = (addr_t)&(info->vm_regs.rcx);
517 case QX86_REGISTER_ECX:
518 *v3_reg = (addr_t)&(info->vm_regs.rcx);
521 case QX86_REGISTER_CX:
522 *v3_reg = (addr_t)&(info->vm_regs.rcx);
525 case QX86_REGISTER_CH:
526 *v3_reg = (addr_t)(&(info->vm_regs.rcx)) + 1;
529 case QX86_REGISTER_CL:
530 *v3_reg = (addr_t)&(info->vm_regs.rcx);
534 case QX86_REGISTER_RDX:
535 *v3_reg = (addr_t)&(info->vm_regs.rdx);
538 case QX86_REGISTER_EDX:
539 *v3_reg = (addr_t)&(info->vm_regs.rdx);
542 case QX86_REGISTER_DX:
543 *v3_reg = (addr_t)&(info->vm_regs.rdx);
546 case QX86_REGISTER_DH:
547 *v3_reg = (addr_t)(&(info->vm_regs.rdx)) + 1;
550 case QX86_REGISTER_DL:
551 *v3_reg = (addr_t)&(info->vm_regs.rdx);
555 case QX86_REGISTER_RBX:
556 *v3_reg = (addr_t)&(info->vm_regs.rbx);
559 case QX86_REGISTER_EBX:
560 *v3_reg = (addr_t)&(info->vm_regs.rbx);
563 case QX86_REGISTER_BX:
564 *v3_reg = (addr_t)&(info->vm_regs.rbx);
567 case QX86_REGISTER_BH:
568 *v3_reg = (addr_t)(&(info->vm_regs.rbx)) + 1;
571 case QX86_REGISTER_BL:
572 *v3_reg = (addr_t)&(info->vm_regs.rbx);
577 case QX86_REGISTER_RSP:
578 *v3_reg = (addr_t)&(info->vm_regs.rsp);
581 case QX86_REGISTER_ESP:
582 *v3_reg = (addr_t)&(info->vm_regs.rsp);
585 case QX86_REGISTER_SP:
586 *v3_reg = (addr_t)&(info->vm_regs.rsp);
589 case QX86_REGISTER_SPL:
590 *v3_reg = (addr_t)&(info->vm_regs.rsp);
594 case QX86_REGISTER_RBP:
595 *v3_reg = (addr_t)&(info->vm_regs.rbp);
598 case QX86_REGISTER_EBP:
599 *v3_reg = (addr_t)&(info->vm_regs.rbp);
602 case QX86_REGISTER_BP:
603 *v3_reg = (addr_t)&(info->vm_regs.rbp);
606 case QX86_REGISTER_BPL:
607 *v3_reg = (addr_t)&(info->vm_regs.rbp);
613 case QX86_REGISTER_RSI:
614 *v3_reg = (addr_t)&(info->vm_regs.rsi);
617 case QX86_REGISTER_ESI:
618 *v3_reg = (addr_t)&(info->vm_regs.rsi);
621 case QX86_REGISTER_SI:
622 *v3_reg = (addr_t)&(info->vm_regs.rsi);
625 case QX86_REGISTER_SIL:
626 *v3_reg = (addr_t)&(info->vm_regs.rsi);
631 case QX86_REGISTER_RDI:
632 *v3_reg = (addr_t)&(info->vm_regs.rdi);
635 case QX86_REGISTER_EDI:
636 *v3_reg = (addr_t)&(info->vm_regs.rdi);
639 case QX86_REGISTER_DI:
640 *v3_reg = (addr_t)&(info->vm_regs.rdi);
643 case QX86_REGISTER_DIL:
644 *v3_reg = (addr_t)&(info->vm_regs.rdi);
652 case QX86_REGISTER_R8:
653 *v3_reg = (addr_t)&(info->vm_regs.r8);
656 case QX86_REGISTER_R8D:
657 *v3_reg = (addr_t)&(info->vm_regs.r8);
660 case QX86_REGISTER_R8W:
661 *v3_reg = (addr_t)&(info->vm_regs.r8);
664 case QX86_REGISTER_R8B:
665 *v3_reg = (addr_t)&(info->vm_regs.r8);
669 case QX86_REGISTER_R9:
670 *v3_reg = (addr_t)&(info->vm_regs.r9);
673 case QX86_REGISTER_R9D:
674 *v3_reg = (addr_t)&(info->vm_regs.r9);
677 case QX86_REGISTER_R9W:
678 *v3_reg = (addr_t)&(info->vm_regs.r9);
681 case QX86_REGISTER_R9B:
682 *v3_reg = (addr_t)&(info->vm_regs.r9);
686 case QX86_REGISTER_R10:
687 *v3_reg = (addr_t)&(info->vm_regs.r10);
690 case QX86_REGISTER_R10D:
691 *v3_reg = (addr_t)&(info->vm_regs.r10);
694 case QX86_REGISTER_R10W:
695 *v3_reg = (addr_t)&(info->vm_regs.r10);
698 case QX86_REGISTER_R10B:
699 *v3_reg = (addr_t)&(info->vm_regs.r10);
703 case QX86_REGISTER_R11:
704 *v3_reg = (addr_t)&(info->vm_regs.r11);
707 case QX86_REGISTER_R11D:
708 *v3_reg = (addr_t)&(info->vm_regs.r11);
711 case QX86_REGISTER_R11W:
712 *v3_reg = (addr_t)&(info->vm_regs.r11);
715 case QX86_REGISTER_R11B:
716 *v3_reg = (addr_t)&(info->vm_regs.r11);
720 case QX86_REGISTER_R12:
721 *v3_reg = (addr_t)&(info->vm_regs.r12);
724 case QX86_REGISTER_R12D:
725 *v3_reg = (addr_t)&(info->vm_regs.r12);
728 case QX86_REGISTER_R12W:
729 *v3_reg = (addr_t)&(info->vm_regs.r12);
732 case QX86_REGISTER_R12B:
733 *v3_reg = (addr_t)&(info->vm_regs.r12);
737 case QX86_REGISTER_R13:
738 *v3_reg = (addr_t)&(info->vm_regs.r13);
741 case QX86_REGISTER_R13D:
742 *v3_reg = (addr_t)&(info->vm_regs.r13);
745 case QX86_REGISTER_R13W:
746 *v3_reg = (addr_t)&(info->vm_regs.r13);
749 case QX86_REGISTER_R13B:
750 *v3_reg = (addr_t)&(info->vm_regs.r13);
754 case QX86_REGISTER_R14:
755 *v3_reg = (addr_t)&(info->vm_regs.r14);
758 case QX86_REGISTER_R14D:
759 *v3_reg = (addr_t)&(info->vm_regs.r14);
762 case QX86_REGISTER_R14W:
763 *v3_reg = (addr_t)&(info->vm_regs.r14);
766 case QX86_REGISTER_R14B:
767 *v3_reg = (addr_t)&(info->vm_regs.r14);
771 case QX86_REGISTER_R15:
772 *v3_reg = (addr_t)&(info->vm_regs.r15);
775 case QX86_REGISTER_R15D:
776 *v3_reg = (addr_t)&(info->vm_regs.r15);
779 case QX86_REGISTER_R15W:
780 *v3_reg = (addr_t)&(info->vm_regs.r15);
783 case QX86_REGISTER_R15B:
784 *v3_reg = (addr_t)&(info->vm_regs.r15);
789 case QX86_REGISTER_RIP:
790 *v3_reg = (addr_t)&(info->rip);
792 return CTRL_REGISTER;
793 case QX86_REGISTER_EIP:
794 *v3_reg = (addr_t)&(info->rip);
796 return CTRL_REGISTER;
797 case QX86_REGISTER_IP:
798 *v3_reg = (addr_t)&(info->rip);
800 return CTRL_REGISTER;
802 case QX86_REGISTER_FLAGS:
803 *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
805 return CTRL_REGISTER;
806 case QX86_REGISTER_EFLAGS:
807 *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
809 return CTRL_REGISTER;
810 case QX86_REGISTER_RFLAGS:
811 *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
813 return CTRL_REGISTER;
815 case QX86_REGISTER_CR0:
816 *v3_reg = (addr_t)&(info->ctrl_regs.cr0);
818 return CTRL_REGISTER;
819 case QX86_REGISTER_CR2:
820 *v3_reg = (addr_t)&(info->ctrl_regs.cr2);
822 return CTRL_REGISTER;
823 case QX86_REGISTER_CR3:
824 *v3_reg = (addr_t)&(info->ctrl_regs.cr3);
826 return CTRL_REGISTER;
827 case QX86_REGISTER_CR4:
828 *v3_reg = (addr_t)&(info->ctrl_regs.cr4);
830 return CTRL_REGISTER;
831 case QX86_REGISTER_CR8:
832 *v3_reg = (addr_t)&(info->ctrl_regs.cr8);
834 return CTRL_REGISTER;
836 case QX86_REGISTER_CR1:
837 case QX86_REGISTER_CR5:
838 case QX86_REGISTER_CR6:
839 case QX86_REGISTER_CR7:
840 case QX86_REGISTER_CR9:
841 case QX86_REGISTER_CR10:
842 case QX86_REGISTER_CR11:
843 case QX86_REGISTER_CR12:
844 case QX86_REGISTER_CR13:
845 case QX86_REGISTER_CR14:
846 case QX86_REGISTER_CR15:
850 case QX86_REGISTER_CS:
851 *v3_reg = (addr_t)&(info->segments.cs);
853 return SEGMENT_REGISTER;
854 case QX86_REGISTER_DS:
855 *v3_reg = (addr_t)&(info->segments.ds);
857 return SEGMENT_REGISTER;
858 case QX86_REGISTER_ES:
859 *v3_reg = (addr_t)&(info->segments.es);
861 return SEGMENT_REGISTER;
862 case QX86_REGISTER_SS:
863 *v3_reg = (addr_t)&(info->segments.ss);
865 return SEGMENT_REGISTER;
866 case QX86_REGISTER_FS:
867 *v3_reg = (addr_t)&(info->segments.fs);
869 return SEGMENT_REGISTER;
870 case QX86_REGISTER_GS:
871 *v3_reg = (addr_t)&(info->segments.gs);
873 return SEGMENT_REGISTER;
876 case QX86_REGISTER_DR0:
877 case QX86_REGISTER_DR1:
878 case QX86_REGISTER_DR2:
879 case QX86_REGISTER_DR3:
880 case QX86_REGISTER_DR4:
881 case QX86_REGISTER_DR5:
882 case QX86_REGISTER_DR6:
883 case QX86_REGISTER_DR7:
884 case QX86_REGISTER_DR8:
885 case QX86_REGISTER_DR9:
886 case QX86_REGISTER_DR10:
887 case QX86_REGISTER_DR11:
888 case QX86_REGISTER_DR12:
889 case QX86_REGISTER_DR13:
890 case QX86_REGISTER_DR14:
891 case QX86_REGISTER_DR15:
895 case QX86_REGISTER_XMM0:
896 case QX86_REGISTER_XMM1:
897 case QX86_REGISTER_XMM2:
898 case QX86_REGISTER_XMM3:
899 case QX86_REGISTER_XMM4:
900 case QX86_REGISTER_XMM5:
901 case QX86_REGISTER_XMM6:
902 case QX86_REGISTER_XMM7:
903 case QX86_REGISTER_XMM8:
904 case QX86_REGISTER_XMM9:
905 case QX86_REGISTER_XMM10:
906 case QX86_REGISTER_XMM11:
907 case QX86_REGISTER_XMM12:
908 case QX86_REGISTER_XMM13:
909 case QX86_REGISTER_XMM14:
910 case QX86_REGISTER_XMM15:
912 case QX86_REGISTER_YMM0:
913 case QX86_REGISTER_YMM1:
914 case QX86_REGISTER_YMM2:
915 case QX86_REGISTER_YMM3:
916 case QX86_REGISTER_YMM4:
917 case QX86_REGISTER_YMM5:
918 case QX86_REGISTER_YMM6:
919 case QX86_REGISTER_YMM7:
920 case QX86_REGISTER_YMM8:
921 case QX86_REGISTER_YMM9:
922 case QX86_REGISTER_YMM10:
923 case QX86_REGISTER_YMM11:
924 case QX86_REGISTER_YMM12:
925 case QX86_REGISTER_YMM13:
926 case QX86_REGISTER_YMM14:
927 case QX86_REGISTER_YMM15:
929 case QX86_REGISTER_MMX0:
930 case QX86_REGISTER_MMX1:
931 case QX86_REGISTER_MMX2:
932 case QX86_REGISTER_MMX3:
933 case QX86_REGISTER_MMX4:
934 case QX86_REGISTER_MMX5:
935 case QX86_REGISTER_MMX6:
936 case QX86_REGISTER_MMX7:
938 case QX86_REGISTER_ST0:
939 case QX86_REGISTER_ST1:
940 case QX86_REGISTER_ST2:
941 case QX86_REGISTER_ST3:
942 case QX86_REGISTER_ST4:
943 case QX86_REGISTER_ST5:
944 case QX86_REGISTER_ST6:
945 case QX86_REGISTER_ST7: