static int do_alignment_ldrhstrh(unsigned long addr, unsigned long instr, struct pt_regs *regs) { unsigned int rd = RD_BITS(instr); if ((instr & 0x01f00ff0) == 0x01000090) goto swp; if ((instr & 0x90) != 0x90 || (instr & 0x60) == 0) goto bad; ai_half += 1; if (user_mode(regs)) goto user; if (LDST_L_BIT(instr)) { unsigned long val; get16_unaligned_check(val, addr); /* signed half-word? */ if (instr & 0x40) val = (signed long)((signed short) val); regs->uregs[rd] = val; } else put16_unaligned_check(regs->uregs[rd], addr); return TYPE_LDST; user: if (LDST_L_BIT(instr)) { unsigned long val; get16t_unaligned_check(val, addr); /* signed half-word? */ if (instr & 0x40) val = (signed long)((signed short) val); regs->uregs[rd] = val; } else put16t_unaligned_check(regs->uregs[rd], addr); return TYPE_LDST; swp: printk(KERN_ERR "Alignment trap: not handling swp instruction\n"); bad: return TYPE_ERROR; fault: return TYPE_FAULT; }
static int do_alignment_ldrhstrh(unsigned long addr, unsigned long instr, struct pt_regs *regs) { unsigned int rd = RD_BITS(instr); ai_half += 1; if (user_mode(regs)) goto user; if (LDST_L_BIT(instr)) { unsigned long val; get16_unaligned_check(val, addr); /* signed half-word? */ if (instr & 0x40) val = (signed long)((signed short) val); regs->uregs[rd] = val; } else put16_unaligned_check(regs->uregs[rd], addr); return TYPE_LDST; user: if (LDST_L_BIT(instr)) { unsigned long val; unsigned int __ua_flags = uaccess_save_and_enable(); get16t_unaligned_check(val, addr); uaccess_restore(__ua_flags); /* signed half-word? */ if (instr & 0x40) val = (signed long)((signed short) val); regs->uregs[rd] = val; } else { unsigned int __ua_flags = uaccess_save_and_enable(); put16t_unaligned_check(regs->uregs[rd], addr); uaccess_restore(__ua_flags); } return TYPE_LDST; fault: return TYPE_FAULT; }
static int do_alignment_ldrhstrh(unsigned long addr, unsigned long instr, struct pt_regs *regs) { unsigned int rd = RD_BITS(instr); ai_half += 1; if (user_mode(regs)) goto user; if (LDST_L_BIT(instr)) { unsigned long val; get16_unaligned_check(val, addr); if (instr & 0x40) val = (signed long)((signed short) val); regs->uregs[rd] = val; } else put16_unaligned_check(regs->uregs[rd], addr); return TYPE_LDST; user: if (LDST_L_BIT(instr)) { unsigned long val; get16t_unaligned_check(val, addr); if (instr & 0x40) val = (signed long)((signed short) val); regs->uregs[rd] = val; } else put16t_unaligned_check(regs->uregs[rd], addr); return TYPE_LDST; fault: return TYPE_FAULT; }