This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: how can I split 1 mov insn into 2 sub_mov and 1 combine?


On Thu, Mar 17, 2011 at 2:11 PM, WANG.Jiong <wong.kwongyuan@gmail.com> wrote:
> define_split should be the correct way to handle this.
> You should first use define_split to break your 256bit pattern and generate
> legitimized 128bit rtl pattern sequence ?for you processor
> mips_output_move should only be used to handle those legitimized one.
>
> ?256 bit rtl pattern ?----> define_split
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?V
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? rtl pattern 1 ? ? ?--->
> mips_output_move () -> ?corresponding instruciton
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? rtl pattern 2 ? ? ...
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? rtl pattern 3 ? ? ...
>
> And I am doubt abour you pattern
>
> (insn 31 30 32 3 hr-simd.c:28 (set (mem/c/i:V4DI (reg/f:DI 253
> virtual-stack-vars) [0 s+0 S32 A256])
> ? ? ? ?(reg:V4DI 257 [ D.5235 ])) -1 (nil))
>
>
> You set the memeory from a register?
>
>
>
> On 03/17/2011 12:59 PM, Liu wrote:
>>
>> hi all
>> Our processor have a outrageous load insn, so I have to make gcc
>> support it. But when I tried some way, I failed.
>> When we suppose a load should be:
>> load_256 ? ? ?$z1, 16($fp) ? ? ? ? ?;load 256bits to a 256bits-wide
>> register.
>> we have to split it into:
>> load_low_128 ? ? ?$z1, 16($fp) ? ? ? ? ?;load 128bits to the low
>> 128bits of a 256bits-wide register.
>> load_low_128 ? ? ?$z2, 32($fp) ? ? ? ? ?;load 128bits to the low
>> 128bits of a 256bits-wide register.
>> combine_2_to_1 ? ? ?$z1, $z1, $z2, 0x20 ? ? ? ? ?;combine them together.
>>
>> in mips_output_move, I can return a string such like "load_256 ? ? ?%0,
>> %1",
>> but I can't return "load_low_128 ? ? ?%0, %1\n
>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?load_low_128 ? ? ?%2, %3\n
>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?combine_2_to_1 ? ? ?%0, %0, %2, 0x20"
>> %3 is %1+16bytes offset, %0 and %2 are 256bits-wide registers, 0x20 is a
>> const.
>>
>> in define_insn "mov<mode>_internal", I can't using emit_insn(gen_xxx()).
>>
>> when I using emit_insn(gen_xxx()) in define_expand "mov<mode>" I get a
>> error like:
>> root@localhost:~/# mips64el-unknown-linux-gnu-gcc -S -march=xx xx-simd.c
>> xx-simd.c: In function 'test_vpaddd_u':
>> xx-simd.c:33:1: error: unrecognizable insn:
>> (insn 31 30 32 3 hr-simd.c:28 (set (mem/c/i:V4DI (reg/f:DI 253
>> virtual-stack-vars) [0 s+0 S32 A256])
>> ? ? ? ? (reg:V4DI 257 [ D.5235 ])) -1 (nil))
>> xx-simd.c:33:1: internal compiler error: in extract_insn, at recog.c:2103
>> Please submit a full bug report,
>>
>> Please show me a path, thank you very much!
>>
>> -Liu
>>
>
>

Sorry  WANG
another toolchain take me several days.

split 256-bits move like:
(define_split
  [(set (match_operand:ZDSOTDWHB 0 "nonimmediate_operand")
	(match_operand:ZDSOTDWHB 1 "move_operand"))]
  "TARGET_1 && reload_completed"
  [(const_int 0)]
{
  mips_split_octupleword_move (operands[0], operands[1]);
  DONE;
})

mips_split_octupleword_move is:
void
mips_split_octupleword_move (rtx dest, rtx src)
{
  rtx addr, tmp_reg, imm8;
  enum machine_mode mode;
  enum rtx_code dest_code, src_code;

  dest_code = GET_CODE (dest);
  src_code = GET_CODE (src);
  mode = GET_MODE (dest);

  if (dest_code == REG && ZZ_REG_P (REGNO(dest)) && src_code == MEM)
    {
      mips_emit_move (dest, src);
      addr = plus_constant (src, 16);
      if (GET_MODE (dest) == V32QImode)
        tmp_reg = gen_reg_rtx (V32QImode);
      else if (GET_MODE (dest) == V16HImode)
	tmp_reg = gen_reg_rtx (V16HImode);
      else if (GET_MODE (dest) == V8SImode)
	tmp_reg = gen_reg_rtx (V8SImode);
      else if (GET_MODE (dest) == V4DImode)
	tmp_reg = gen_reg_rtx (V4DImode);
      else if (GET_MODE (dest) == V2TImode)
	tmp_reg = gen_reg_rtx (V2TImode);
      else if (GET_MODE (dest) == OImode)
	tmp_reg = gen_reg_rtx (OImode);
      else if (GET_MODE (dest) == V8SFmode)
	tmp_reg = gen_reg_rtx (V8SFmode);
      else if (GET_MODE (dest) == V4DFmode)
	tmp_reg = gen_reg_rtx (V4DFmode);
      else
	printf("Can't alloc Pseudo-Register for vload. \n");
      mips_emit_move (tmp_reg, addr);
      imm8 = GEN_INT(0x20);
      emit_insn (gen_vpermutqi (dest, dest, tmp_reg, imm8));
    }
  else if (src_code == REG && ZZ_REG_P (REGNO(src)) && dest_code ==MEM)
    {
      mips_emit_move (dest, src);
      addr = plus_constant (src, 16);
      if (GET_MODE (dest) == V32QImode)
        tmp_reg = gen_reg_rtx (V32QImode);
      else if (GET_MODE (dest) == V16HImode)
	tmp_reg = gen_reg_rtx (V16HImode);
      else if (GET_MODE (dest) == V8SImode)
	tmp_reg = gen_reg_rtx (V8SImode);
      else if (GET_MODE (dest) == V4DImode)
	tmp_reg = gen_reg_rtx (V4DImode);
      else if (GET_MODE (dest) == V2TImode)
	tmp_reg = gen_reg_rtx (V2TImode);
      else if (GET_MODE (dest) == OImode)
	tmp_reg = gen_reg_rtx (OImode);
      else if (GET_MODE (dest) == V8SFmode)
	tmp_reg = gen_reg_rtx (V8SFmode);
      else if (GET_MODE (dest) == V4DFmode)
	tmp_reg = gen_reg_rtx (V4DFmode);
      else
	printf("Can't alloc Pseudo-Register for vstore. \n");
      imm8 = GEN_INT(0x01);
      emit_insn (gen_vpextrv2ti (tmp_reg, dest, imm8));
      mips_emit_move (tmp_reg, addr);
    }
}

then mov<mode>:
(define_expand "mov<mode>"
  [(set (match_operand:ZDSOTDWHB 0)
	(match_operand:ZDSOTDWHB 1))]
  "TARGET_VECTORS"
{
  if (mips_legitimize_move (<MODE>mode, operands[0], operands[1]))
    DONE;
})

(define_insn "mov<mode>_internal"
  [(set (match_operand:ZDSOTDWHB 0 "nonimmediate_operand" "=m,Z,Z")
	(match_operand:ZDSOTDWHB 1 "move_operand"          "Z,m,Z"))]
  "TARGET_VECTORS"
  { return mips_output_move (operands[0], operands[1]); }
[(set_attr "move_type" "vmov")])

mips_output_move has this code:
  if (dest_code == REG && ZZ_REG_P (REGNO(dest)))
    {
      if (src_code == MEM)
        {
	  return "vldql\t%0,%1";
	}
    }

  if (src_code == REG && HR_REG_P (REGNO(src)))
    {
      if (dest_code == MEM)
	{
	  return "vstql\t%1,%0";
	}
    }


make and test it, get a error:

root@localhost:~/hr1-toolchain/test# mips64el-unknown-linux-gnu-gcc
-march=zz1 -S vpaddd.c
vpaddd.c: In function 'test_vpaddd_u':
vpaddd.c:33:1: internal compiler error: in gen_reg_rtx, at emit-rtl.c:863
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.

emit-rtl.c:863 is  gcc_assert (can_create_pseudo_p ());


I have no ideas...


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]