diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 0dc637fc08aca..bf62849fba0c3 100644 --- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -9053,10 +9053,11 @@ bool ARMAsmParser::processInstruction(MCInst &Inst, TmpInst.setOpcode(Inst.getOpcode() == ARM::t2LDR_PRE_imm ? ARM::t2LDR_PRE : ARM::t2LDR_POST); TmpInst.addOperand(Inst.getOperand(0)); // Rt - TmpInst.addOperand(Inst.getOperand(4)); // Rt_wb + TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb TmpInst.addOperand(Inst.getOperand(1)); // Rn TmpInst.addOperand(Inst.getOperand(2)); // imm TmpInst.addOperand(Inst.getOperand(3)); // CondCode + TmpInst.addOperand(Inst.getOperand(4)); Inst = TmpInst; return true; } @@ -9066,11 +9067,12 @@ bool ARMAsmParser::processInstruction(MCInst &Inst, MCInst TmpInst; TmpInst.setOpcode(Inst.getOpcode() == ARM::t2STR_PRE_imm ? ARM::t2STR_PRE : ARM::t2STR_POST); - TmpInst.addOperand(Inst.getOperand(4)); // Rt_wb + TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb TmpInst.addOperand(Inst.getOperand(0)); // Rt TmpInst.addOperand(Inst.getOperand(1)); // Rn TmpInst.addOperand(Inst.getOperand(2)); // imm TmpInst.addOperand(Inst.getOperand(3)); // CondCode + TmpInst.addOperand(Inst.getOperand(4)); Inst = TmpInst; return true; } @@ -9092,10 +9094,11 @@ bool ARMAsmParser::processInstruction(MCInst &Inst, ? ARM::t2LDRB_PRE : ARM::t2LDRB_POST); TmpInst.addOperand(Inst.getOperand(0)); // Rt - TmpInst.addOperand(Inst.getOperand(4)); // Rt_wb + TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb TmpInst.addOperand(Inst.getOperand(1)); // Rn TmpInst.addOperand(Inst.getOperand(2)); // imm TmpInst.addOperand(Inst.getOperand(3)); // CondCode + TmpInst.addOperand(Inst.getOperand(4)); Inst = TmpInst; return true; } @@ -9116,11 +9119,12 @@ bool ARMAsmParser::processInstruction(MCInst &Inst, TmpInst.setOpcode(Inst.getOpcode() == ARM::t2STRB_PRE_imm ? ARM::t2STRB_PRE : ARM::t2STRB_POST); - TmpInst.addOperand(Inst.getOperand(4)); // Rt_wb + TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb TmpInst.addOperand(Inst.getOperand(0)); // Rt TmpInst.addOperand(Inst.getOperand(1)); // Rn TmpInst.addOperand(Inst.getOperand(2)); // imm TmpInst.addOperand(Inst.getOperand(3)); // CondCode + TmpInst.addOperand(Inst.getOperand(4)); Inst = TmpInst; return true; } @@ -9142,10 +9146,11 @@ bool ARMAsmParser::processInstruction(MCInst &Inst, ? ARM::t2LDRH_PRE : ARM::t2LDRH_POST); TmpInst.addOperand(Inst.getOperand(0)); // Rt - TmpInst.addOperand(Inst.getOperand(4)); // Rt_wb + TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb TmpInst.addOperand(Inst.getOperand(1)); // Rn TmpInst.addOperand(Inst.getOperand(2)); // imm TmpInst.addOperand(Inst.getOperand(3)); // CondCode + TmpInst.addOperand(Inst.getOperand(4)); Inst = TmpInst; return true; } @@ -9166,11 +9171,12 @@ bool ARMAsmParser::processInstruction(MCInst &Inst, TmpInst.setOpcode(Inst.getOpcode() == ARM::t2STRH_PRE_imm ? ARM::t2STRH_PRE : ARM::t2STRH_POST); - TmpInst.addOperand(Inst.getOperand(4)); // Rt_wb + TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb TmpInst.addOperand(Inst.getOperand(0)); // Rt TmpInst.addOperand(Inst.getOperand(1)); // Rn TmpInst.addOperand(Inst.getOperand(2)); // imm TmpInst.addOperand(Inst.getOperand(3)); // CondCode + TmpInst.addOperand(Inst.getOperand(4)); Inst = TmpInst; return true; } @@ -9192,10 +9198,11 @@ bool ARMAsmParser::processInstruction(MCInst &Inst, ? ARM::t2LDRSB_PRE : ARM::t2LDRSB_POST); TmpInst.addOperand(Inst.getOperand(0)); // Rt - TmpInst.addOperand(Inst.getOperand(4)); // Rt_wb + TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb TmpInst.addOperand(Inst.getOperand(1)); // Rn TmpInst.addOperand(Inst.getOperand(2)); // imm TmpInst.addOperand(Inst.getOperand(3)); // CondCode + TmpInst.addOperand(Inst.getOperand(4)); Inst = TmpInst; return true; } @@ -9217,10 +9224,11 @@ bool ARMAsmParser::processInstruction(MCInst &Inst, ? ARM::t2LDRSH_PRE : ARM::t2LDRSH_POST); TmpInst.addOperand(Inst.getOperand(0)); // Rt - TmpInst.addOperand(Inst.getOperand(4)); // Rt_wb + TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb TmpInst.addOperand(Inst.getOperand(1)); // Rn TmpInst.addOperand(Inst.getOperand(2)); // imm TmpInst.addOperand(Inst.getOperand(3)); // CondCode + TmpInst.addOperand(Inst.getOperand(4)); Inst = TmpInst; return true; } diff --git a/llvm/test/tools/llvm-mca/ARM/m4-ldr-str-w.s b/llvm/test/tools/llvm-mca/ARM/m4-ldr-str-w.s new file mode 100644 index 0000000000000..cb4eeaff4b2a8 --- /dev/null +++ b/llvm/test/tools/llvm-mca/ARM/m4-ldr-str-w.s @@ -0,0 +1,80 @@ +# NOTE: Assertions have been autogenerated by utils/update_mca_test_checks.py +# RUN: llvm-mca -mtriple thumbv7m-none-eabi -mcpu=cortex-m4 < %s | FileCheck %s +str.w r1, [r0], #16 +str.w r1, [r0, 16]! +strb.w r1, [r0], #16 +strb.w r1, [r0, 16]! +strh.w r1, [r0], #16 +strh.w r1, [r0, 16]! +ldr.w r1, [r0], #16 +ldr.w r1, [r0, 16]! +ldrb.w r1, [r0], #16 +ldrb.w r1, [r0, 16]! +ldrh.w r1, [r0], #16 +ldrh.w r1, [r0, 16]! +ldrsb.w r1, [r0], #16 +ldrsb.w r1, [r0, 16]! +ldrsh.w r1, [r0], #16 +ldrsh.w r1, [r0, 16]! + +# CHECK: Iterations: 100 +# CHECK-NEXT: Instructions: 1600 +# CHECK-NEXT: Total Cycles: 2601 +# CHECK-NEXT: Total uOps: 1600 + +# CHECK: Dispatch Width: 1 +# CHECK-NEXT: uOps Per Cycle: 0.62 +# CHECK-NEXT: IPC: 0.62 +# CHECK-NEXT: Block RThroughput: 16.0 + +# CHECK: Instruction Info: +# CHECK-NEXT: [1]: #uOps +# CHECK-NEXT: [2]: Latency +# CHECK-NEXT: [3]: RThroughput +# CHECK-NEXT: [4]: MayLoad +# CHECK-NEXT: [5]: MayStore +# CHECK-NEXT: [6]: HasSideEffects (U) + +# CHECK: [1] [2] [3] [4] [5] [6] Instructions: +# CHECK-NEXT: 1 1 1.00 * str r1, [r0], #16 +# CHECK-NEXT: 1 1 1.00 * str r1, [r0, #16]! +# CHECK-NEXT: 1 1 1.00 * strb r1, [r0], #16 +# CHECK-NEXT: 1 1 1.00 * strb r1, [r0, #16]! +# CHECK-NEXT: 1 1 1.00 * strh r1, [r0], #16 +# CHECK-NEXT: 1 1 1.00 * strh r1, [r0, #16]! +# CHECK-NEXT: 1 2 1.00 * ldr r1, [r0], #16 +# CHECK-NEXT: 1 2 1.00 * ldr r1, [r0, #16]! +# CHECK-NEXT: 1 2 1.00 * ldrb r1, [r0], #16 +# CHECK-NEXT: 1 2 1.00 * ldrb r1, [r0, #16]! +# CHECK-NEXT: 1 2 1.00 * ldrh r1, [r0], #16 +# CHECK-NEXT: 1 2 1.00 * ldrh r1, [r0, #16]! +# CHECK-NEXT: 1 2 1.00 * ldrsb r1, [r0], #16 +# CHECK-NEXT: 1 2 1.00 * ldrsb r1, [r0, #16]! +# CHECK-NEXT: 1 2 1.00 * ldrsh r1, [r0], #16 +# CHECK-NEXT: 1 2 1.00 * ldrsh r1, [r0, #16]! + +# CHECK: Resources: +# CHECK-NEXT: [0] - M4Unit + +# CHECK: Resource pressure per iteration: +# CHECK-NEXT: [0] +# CHECK-NEXT: 16.00 + +# CHECK: Resource pressure by instruction: +# CHECK-NEXT: [0] Instructions: +# CHECK-NEXT: 1.00 str r1, [r0], #16 +# CHECK-NEXT: 1.00 str r1, [r0, #16]! +# CHECK-NEXT: 1.00 strb r1, [r0], #16 +# CHECK-NEXT: 1.00 strb r1, [r0, #16]! +# CHECK-NEXT: 1.00 strh r1, [r0], #16 +# CHECK-NEXT: 1.00 strh r1, [r0, #16]! +# CHECK-NEXT: 1.00 ldr r1, [r0], #16 +# CHECK-NEXT: 1.00 ldr r1, [r0, #16]! +# CHECK-NEXT: 1.00 ldrb r1, [r0], #16 +# CHECK-NEXT: 1.00 ldrb r1, [r0, #16]! +# CHECK-NEXT: 1.00 ldrh r1, [r0], #16 +# CHECK-NEXT: 1.00 ldrh r1, [r0, #16]! +# CHECK-NEXT: 1.00 ldrsb r1, [r0], #16 +# CHECK-NEXT: 1.00 ldrsb r1, [r0, #16]! +# CHECK-NEXT: 1.00 ldrsh r1, [r0], #16 +# CHECK-NEXT: 1.00 ldrsh r1, [r0, #16]!