• P
    arm: translate.c: Fix smlald Instruction · 33bbd75a
    Peter Crosthwaite 提交于
    The smlald (and probably smlsld) instruction was doing incorrect sign
    extensions of the operands amongst 64bit result calculation. The
    instruction psuedo-code is:
    
     operand2 = if m_swap then ROR(R[m],16) else R[m];
     product1 = SInt(R[n]<15:0>) * SInt(operand2<15:0>);
     product2 = SInt(R[n]<31:16>) * SInt(operand2<31:16>);
     result = product1 + product2 + SInt(R[dHi]:R[dLo]);
     R[dHi] = result<63:32>;
     R[dLo] = result<31:0>;
    
    The result calculation should be done in 64 bit arithmetic, and hence
    product1 and product2 should be sign extended to 64b before calculation.
    
    The current implementation was adding product1 and product2 together
    then sign-extending the intermediate result leading to false negatives.
    
    E.G. if product1 = product2 = 0x4000000, their sum = 0x80000000, which
    will be incorrectly interpreted as -ve on sign extension.
    
    We fix by doing the 64b extensions on both product1 and product2 before
    any addition/subtraction happens.
    
    We also fix where we were possibly incorrectly setting the Q saturation
    flag for SMLSLD, which the ARM ARM specifically says is not set.
    Reported-by: NChristina Smith <christina.smith@xilinx.com>
    Signed-off-by: NPeter Crosthwaite <peter.crosthwaite@xilinx.com>
    Reviewed-by: NPeter Maydell <peter.maydell@linaro.org>
    Message-id: 2cddb6f5a15be4ab8d2160f3499d128ae93d304d.1397704570.git.peter.crosthwaite@xilinx.com
    Cc: qemu-stable@nongnu.org
    Signed-off-by: NPeter Maydell <peter.maydell@linaro.org>
    33bbd75a
translate.c 386.3 KB