bromley (02/24/83)
In generating code to extract values from fields, the compiler uses only the extv/extvz instructions. The optimizer changes all extractions of byte/word fields on byte/word boundaries to cvt{b,w}l or movz{b,w}l depending on the field being signed or unsigned. However, it does this incorrectly for word size fields on non-longword boundaries. The specific transformations it performs are: extv $n*16, $16, A, B ==> cvtwl n+A,B extvz $n*16, $16, A, B ==> movzwl n+A,B The actual address of the field is 2n+A, as we are dealing with a word sized field and not a byte sized one. The correct transformations are then: extv $n*16, $16, A, B ==> cvtwl 2n+A,B extvz $n*16, $16, A, B ==> movzwl 2n+A,B The code that implements this is in c21.c and is easily fixed. The changes are: 263c263 < ** extv $n*16,$16,A,B > cvtwl n+A,B --- > ** extv $n*16,$16,A,B > cvtwl 2n+A,B 265c265 < ** extzv $n*16,$16,A,B > movzwl n+A,B --- > ** extzv $n*16,$16,A,B > movzwl 2n+A,B 310c310,312 < sprintf(regs[RT1], "%d%s%s", coff, regs[RT3][0]=='(' ? "":"+", --- > sprintf(regs[RT1], "%d%s%s", > (flen == 8 ? coff : 2*coff), > (regs[RT3][0] == '(' ? "" : "+"), Mark Bromley cornell