ia64/xen-unstable

changeset 16114:503756587ccf

[IA64] Correctly decode imm fields in mmio.c

Immediate field of ia64 instructions are 2's complement coded.

Instructions whose imm field was negative were not
correctly emulated in mmio.c

Signed-off-by: Tristan Gingold <tgingold@free.fr>
author Alex Williamson <alex.williamson@hp.com>
date Mon Oct 15 11:31:29 2007 -0600 (2007-10-15)
parents 2e13bfcf4abb
children cd889a7ccae4
files xen/arch/ia64/vmx/mmio.c
line diff
     1.1 --- a/xen/arch/ia64/vmx/mmio.c	Fri Oct 12 15:02:06 2007 -0600
     1.2 +++ b/xen/arch/ia64/vmx/mmio.c	Mon Oct 15 11:31:29 2007 -0600
     1.3 @@ -318,7 +318,8 @@ void emulate_io_inst(VCPU *vcpu, u64 pad
     1.4      IA64_BUNDLE bundle;
     1.5      int slot, dir=0, inst_type;
     1.6      size_t size;
     1.7 -    u64 data, post_update, slot1a, slot1b, temp;
     1.8 +    u64 data, slot1a, slot1b, temp, update_reg;
     1.9 +    s32 imm;
    1.10      INST64 inst;
    1.11  
    1.12      regs = vcpu_regs(vcpu);
    1.13 @@ -355,8 +356,8 @@ void emulate_io_inst(VCPU *vcpu, u64 pad
    1.14          dir = IOREQ_READ;     //write
    1.15          size = (inst.M2.x6 & 0x3);
    1.16          vcpu_get_gr_nat(vcpu, inst.M2.r3, &temp);
    1.17 -        vcpu_get_gr_nat(vcpu, inst.M2.r2, &post_update);
    1.18 -        temp += post_update;
    1.19 +        vcpu_get_gr_nat(vcpu, inst.M2.r2, &update_reg);
    1.20 +        temp += update_reg;
    1.21          vcpu_set_gr(vcpu, inst.M2.r3, temp, 0);
    1.22      }
    1.23      // Integer Load/Store + Imm update
    1.24 @@ -367,20 +368,16 @@ void emulate_io_inst(VCPU *vcpu, u64 pad
    1.25              dir = IOREQ_WRITE;     // write
    1.26              vcpu_get_gr_nat(vcpu, inst.M5.r2, &data);
    1.27              vcpu_get_gr_nat(vcpu, inst.M5.r3, &temp);
    1.28 -            post_update = (inst.M5.i << 7) + inst.M5.imm7;
    1.29 -            if (inst.M5.s)
    1.30 -                temp -= post_update;
    1.31 -            else
    1.32 -                temp += post_update;
    1.33 +            imm =
    1.34 +                (inst.M5.s << 31) | (inst.M5.i << 30) | (inst.M5.imm7 << 23);
    1.35 +            temp += imm >> 23;
    1.36              vcpu_set_gr(vcpu, inst.M5.r3, temp, 0);
    1.37          } else if ((inst.M3.x6 >> 2) < 0xb) {   // read
    1.38              dir = IOREQ_READ;
    1.39              vcpu_get_gr_nat(vcpu, inst.M3.r3, &temp);
    1.40 -            post_update = (inst.M3.i << 7) + inst.M3.imm7;
    1.41 -            if (inst.M3.s)
    1.42 -                temp -= post_update;
    1.43 -            else
    1.44 -                temp += post_update;
    1.45 +            imm =
    1.46 +                (inst.M3.s << 31) | (inst.M3.i << 30) | (inst.M3.imm7 << 23);
    1.47 +            temp += imm >> 23;
    1.48              vcpu_set_gr(vcpu, inst.M3.r3, temp, 0);
    1.49          }
    1.50      }
    1.51 @@ -407,11 +404,9 @@ void emulate_io_inst(VCPU *vcpu, u64 pad
    1.52          dir = IOREQ_WRITE;
    1.53          vcpu_get_fpreg(vcpu, inst.M10.f2, &v);
    1.54          vcpu_get_gr_nat(vcpu, inst.M10.r3, &temp);
    1.55 -        post_update = (inst.M10.i << 7) + inst.M10.imm7;
    1.56 -        if (inst.M10.s)
    1.57 -            temp -= post_update;
    1.58 -        else
    1.59 -            temp += post_update;
    1.60 +        imm =
    1.61 +            (inst.M10.s << 31) | (inst.M10.i << 30) | (inst.M10.imm7 << 23);
    1.62 +        temp += imm >> 23;
    1.63          vcpu_set_gr(vcpu, inst.M10.r3, temp, 0);
    1.64  
    1.65          /* Write high word.
    1.66 @@ -431,11 +426,9 @@ void emulate_io_inst(VCPU *vcpu, u64 pad
    1.67          vcpu_get_fpreg(vcpu, inst.M10.f2, &v);
    1.68          data = v.u.bits[0]; /* Significand.  */
    1.69          vcpu_get_gr_nat(vcpu, inst.M10.r3, &temp);
    1.70 -        post_update = (inst.M10.i << 7) + inst.M10.imm7;
    1.71 -        if (inst.M10.s)
    1.72 -            temp -= post_update;
    1.73 -        else
    1.74 -            temp += post_update;
    1.75 +        imm =
    1.76 +            (inst.M10.s << 31) | (inst.M10.i << 30) | (inst.M10.imm7 << 23);
    1.77 +        temp += imm >> 23;
    1.78          vcpu_set_gr(vcpu, inst.M10.r3, temp, 0);
    1.79      }
    1.80  //    else if(inst.M6.major==6&&inst.M6.m==0&&inst.M6.x==0&&inst.M6.x6==3){
    1.81 @@ -446,11 +439,9 @@ void emulate_io_inst(VCPU *vcpu, u64 pad
    1.82      //  lfetch - do not perform accesses.
    1.83      else if (inst.M15.major== 7 && inst.M15.x6 >=0x2c && inst.M15.x6 <= 0x2f) {
    1.84          vcpu_get_gr_nat(vcpu, inst.M15.r3, &temp);
    1.85 -        post_update = (inst.M15.i << 7) + inst.M15.imm7;
    1.86 -        if (inst.M15.s)
    1.87 -            temp -= post_update;
    1.88 -        else
    1.89 -            temp += post_update;
    1.90 +        imm =
    1.91 +            (inst.M15.s << 31) | (inst.M15.i << 30) | (inst.M15.imm7 << 23);
    1.92 +        temp += imm >> 23;
    1.93          vcpu_set_gr(vcpu, inst.M15.r3, temp, 0);
    1.94  
    1.95          vcpu_increment_iip(vcpu);