On Wed, Jun 29, 2016 at 9:59 AM, Virendra Pathak <virendra.pat...@broadcom.com> wrote: > Hi gcc-patches group, > > I am working on adding vulcan.md (machine description) for vulcan cpu > in the aarch64 port. However, before proposing the final patch, I would like > the basic approach to be reviewed by you all (as changes are there in > aarch64.md) > > In vulcan, a (load/store) instruction could be scheduled to cpu units in > different way based on the addressing mode(e.g. load, or load+integer). > So the requirement is to identify the addressing mode of (load/store) > instruction's operand while scheduling. > > For this purpose, a new attribute "addr_type" has been added in the > aarch64.md file. This helps in identifying which operands of (load/store) > instruction should be considered for finding the addressing mode. > > vulcan.md, while scheduling, calls a new function aarch64_mem_type_p > in the aarch64.c (via match_test) to decide the scheduling option based > on the addressing mode. > > I have copied the code snippet below (complete patch is attached with > this mail). > > Kindly review and give your feedback/comment. > Also if you think there could be an better alternative way, kindly suggest.
Since this is only about post and pre increment being split into two micro-ops. I suspect something like what rs600 back-end does is better: ;; Does this instruction use update addressing? ;; This is used for load and store insns. See the comments for "indexed". (define_attr "update" "no,yes" (if_then_else (ior (match_operand 0 "update_address_mem") (match_operand 1 "update_address_mem")) (const_string "yes") (const_string "no"))) Where update_address_mem is defined as: ;; Return 1 if the operand is a MEM with an update-form address. This may ;; also include update-indexed form. (define_special_predicate "update_address_mem" (match_test "(MEM_P (op) && (GET_CODE (XEXP (op, 0)) == PRE_INC || GET_CODE (XEXP (op, 0)) == PRE_DEC || GET_CODE (XEXP (op, 0)) == PRE_MODIFY))")) Note you need to include the POST ones for AARCH64 but it should be similar enough. And then you just check the attr update. Thanks, Andrew > > Thanks in advance for your time. > > <Code Snippet> > > FILE - gcc/config/aarch64/aarch64-protos.h > > /* Mask bits to use for for aarch64_mem_type_p. Unshifted/shifted index > register variants are separated for scheduling purposes because the > distinction matters on some cores. */ > #define AARCH64_ADDR_REG_IMM 0x01 > #define AARCH64_ADDR_REG_WB 0x02 > #define AARCH64_ADDR_REG_REG 0x04 > #define AARCH64_ADDR_REG_SHIFT 0x08 > #define AARCH64_ADDR_REG_EXT 0x10 > #define AARCH64_ADDR_REG_SHIFT_EXT 0x20 > #define AARCH64_ADDR_LO_SUM 0x40 > #define AARCH64_ADDR_SYMBOLIC 0x80 > > > > > FILE - gcc/config/aarch64/aarch64.md > > (define_attr "addr_type" "none,op0,op1,op0addr,op1addr,lo_sum,wb" > (const_string "none")) > > > (define_insn "*mov<mode>_aarch64" > [(set (match_operand:SHORT 0 "nonimmediate_operand" "=r,r, > *w,r,*w, m, m, r,*w,*w") > (match_operand:SHORT 1 "general_operand" " r,M,D<hq>,m, > m,rZ,*w,*w, r,*w"))] > "(register_operand (operands[0], <MODE>mode) > || aarch64_reg_or_zero (operands[1], <MODE>mode))" > > { > switch (which_alternative) > { > case 0: > return "mov\t%w0, %w1"; > case 1: > return "mov\t%w0, %1"; > case 2: > return aarch64_output_scalar_simd_mov_immediate (operands[1], > <MODE>mode); > case 3: > return "ldr<size>\t%w0, %1"; > case 4: > return "ldr\t%<size>0, %1"; > case 5: > return "str<size>\t%w1, %0"; > case 6: > return "str\t%<size>1, %0"; > case 7: > return "umov\t%w0, %1.<v>[0]"; > case 8: > return "dup\t%0.<Vallxd>, %w1"; > case 9: > return "dup\t%<Vetype>0, %1.<v>[0]"; > default: > gcc_unreachable (); > } > } > [(set_attr "type" "mov_reg,mov_imm,neon_move,load1,load1,store1,store1,\ > neon_to_gp<q>,neon_from_gp<q>,neon_dup") > (set_attr "simd" "*,*,yes,*,*,*,*,yes,yes,yes") > (set_attr "addr_type" "*,*,*,op1,op1,op0,op0,*,*,*")] > ) > > > > > FILE - gcc/config/aarch64/vulcan.md > ;; Integer loads and stores. > > (define_insn_reservation "vulcan_load_basic" 4 > (and (eq_attr "tune" "vulcan") > (eq_attr "type" "load1") > (match_test "aarch64_mem_type_p (insn, AARCH64_ADDR_SYMBOLIC > | AARCH64_ADDR_REG_IMM > | AARCH64_ADDR_LO_SUM)")) > "vulcan_ls01") > > (define_insn_reservation "vulcan_load_automod" 4 > (and (eq_attr "tune" "vulcan") > (eq_attr "type" "load1") > (match_test "aarch64_mem_type_p (insn, AARCH64_ADDR_REG_WB)")) > "vulcan_ls01,vulcan_i012") > > > > > FILE - gcc/config/aarch64/aarch64.c > > /* Return TRUE if INSN uses an address that satisfies any of the (non-strict) > addressing modes specified by MASK. This is intended for use in scheduling > models that are sensitive to the form of address used by some particular > instruction. */ > > bool > aarch64_mem_type_p (rtx_insn *insn, unsigned HOST_WIDE_INT mask) > { > aarch64_address_info info; > bool valid; > attr_addr_type addr_type; > rtx mem, addr; > machine_mode mode; > > addr_type = get_attr_addr_type (insn); > > switch (addr_type) > { > case ADDR_TYPE_WB: > info.type = ADDRESS_REG_WB; > break; > > case ADDR_TYPE_LO_SUM: > info.type = ADDRESS_LO_SUM; > break; > > case ADDR_TYPE_OP0: > case ADDR_TYPE_OP1: > extract_insn_cached (insn); > > mem = recog_data.operand[(addr_type == ADDR_TYPE_OP0) ? 0 : 1]; > > gcc_assert (MEM_P (mem)); > > addr = XEXP (mem, 0); > mode = GET_MODE (mem); > > classify: > valid = aarch64_classify_address (&info, addr, mode, MEM, false); > if (!valid) > return false; > > break; > > case ADDR_TYPE_OP0ADDR: > case ADDR_TYPE_OP1ADDR: > extract_insn_cached (insn); > > addr = recog_data.operand[(addr_type == ADDR_TYPE_OP0ADDR) ? 0 : 1]; > mode = DImode; > goto classify; > > case ADDR_TYPE_NONE: > return false; > } > > switch (info.type) > { > case ADDRESS_REG_IMM: > return (mask & AARCH64_ADDR_REG_IMM) != 0; > case ADDRESS_REG_WB: > return (mask & AARCH64_ADDR_REG_WB) != 0; > case ADDRESS_REG_REG: > if (info.shift == 0) > return (mask & AARCH64_ADDR_REG_REG) != 0; > else > return (mask & AARCH64_ADDR_REG_SHIFT) != 0; > case ADDRESS_REG_UXTW: > case ADDRESS_REG_SXTW: > if (info.shift == 0) > return (mask & AARCH64_ADDR_REG_EXT) != 0; > else > return (mask & AARCH64_ADDR_REG_SHIFT_EXT) != 0; > case ADDRESS_LO_SUM: > return (mask & AARCH64_ADDR_LO_SUM) != 0; > case ADDRESS_SYMBOLIC: > return (mask & AARCH64_ADDR_SYMBOLIC) != 0; > default: > return false; > } > } > > > <END> > > with regards, > Virendra Pathak