2009/2/26 Dave Korn <dave.korn.cyg...@googlemail.com>: > daniel tian wrote: > >> there is a 'movm' problem that puzzled me. In my target machine, >> to load a large immediate data, can only move into zero register "R0". >> but R0 is a generally register. I defined the the way in the >> following: >> >> if the immediate data (op1) is larger than 1024 >> then do >> { >> emit_move_insn(r0_reg_rtx, gen_rtx_CONST_INT(SImode, op1)); >> //Move the immediate data into R0 register >> emit_move_insn(force_reg (mode, operands[0]), r0_reg_rtx); >> //move r0 to default register. >> } > > When/where/how are you calling this code?
while in "define_expand movsi" pattern, It will call this code, and if the source operand is larget immediate, it will emit the two RTLs. So if the destination reg is 49 (pseudo reg num), my solution will move the symbol or large immediate into R0, then move the R0 into pseudo register 49. I mean whether there is any way let the gcc know to set a default distination reg being R0 while reloading symbol or large immediate. > >> the address label "common_reg " used many times. I think it will >> load one time. But after optimized with '-Os' or '-O2', it still loads >> the label "common_reg " six times.. > > I wonder if you're generating it too late for the optimisers to do anything? I dumped the *.00.expand and *.21.sched file. I think it generates the RTL before optimiser working. But I doubt whether the code like this is optimized in RTL, maybe before. *.00.expand (part of it, the integral one is too long): (insn 22 21 23 1 (set (reg:SI 0 R0) (const:SI (plus:SI (symbol_ref:SI ("common_reg") [flags 0x2] <var_decl 0xb7c751b0 common_reg>) (const_int 69 [0x45])))) -1 (nil) (nil)) (insn 23 22 24 1 (set (reg/f:SI 49) (reg:SI 0 R0)) -1 (nil) (expr_list:REG_EQUAL (const:SI (plus:SI (symbol_ref:SI ("common_reg") [flags 0x2] <var_decl 0xb7c751b0 common_reg>) (const_int 69 [0x45]))) (nil))) (insn 24 23 25 1 (set (reg:SI 0 R0) (symbol_ref:SI ("DiffReg") [flags 0x2] <var_decl 0xb7c753cc DiffReg>)) -1 (nil) (nil)) (insn 25 24 26 1 (set (reg/f:SI 50) (reg:SI 0 R0)) -1 (nil) (expr_list:REG_EQUAL (symbol_ref:SI ("DiffReg") [flags 0x2] <var_decl 0xb7c753cc DiffReg>) (nil))) (insn 26 25 27 1 (set (reg:QI 51) (mem:QI (plus:SI (reg:SI 47 [ D.1073 ]) (reg/f:SI 50)) [0 S1 A8])) -1 (nil) (nil)) (insn 27 26 29 1 (set (mem/s:QI (reg/f:SI 49) [0 common_reg+69 S1 A8]) (reg:QI 51)) -1 (nil) (nil)) (insn 29 27 30 1 (set (reg:SI 0 R0) (const:SI (plus:SI (symbol_ref:SI ("common_reg") [flags 0x2] <var_decl 0xb7c751b0 common_reg>) (const_int 73 [0x49])))) -1 (nil) (nil)) (insn 30 29 31 1 (set (reg/f:SI 52) (reg:SI 0 R0)) -1 (nil) (expr_list:REG_EQUAL (const:SI (plus:SI (symbol_ref:SI ("common_reg") [flags 0x2] <var_decl 0xb7c751b0 common_reg>) (const_int 73 [0x49]))) (nil))) (insn 31 30 32 1 (set (reg:SI 0 R0) (const:SI (plus:SI (symbol_ref:SI ("DiffReg") [flags 0x2] <var_decl 0xb7c753cc DiffReg>) (const_int 36 [0x24])))) -1 (nil) (nil)) (insn 32 31 33 1 (set (reg/f:SI 53) (reg:SI 0 R0)) -1 (nil) (expr_list:REG_EQUAL (const:SI (plus:SI (symbol_ref:SI ("DiffReg") [flags 0x2] <var_decl 0xb7c753cc DiffReg>) (const_int 36 [0x24]))) (nil))) (insn 33 32 34 1 (set (reg:QI 54) (mem:QI (plus:SI (reg:SI 47 [ D.1073 ]) (reg/f:SI 53)) [0 S1 A8])) -1 (nil) (nil)) (insn 34 33 36 1 (set (mem/s:QI (reg/f:SI 52) [0 common_reg+73 S1 A8]) (reg:QI 54)) -1 (nil) (nil)) .............. Does the load two labels "common_reg"", "DiffReg" interlaced caused the optimization confused? I mean there are two label need to load, then after load one, move the value in R0 to another register, and then load another label. So It will only load every label one time. Here is the *.21.sched file: ;; ====================================================== ;; -- basic block 0 from 20 to 70 -- before reload ;; ====================================================== ;; 0--> 20 r48=[`iFrequency'] :rice_load,nothing ;; 1--> 24 R0=`DiffReg' :nothing ;; 2--> 21 r47=zxn(r48) :nothing ;; 3--> 25 r50=R0 :nothing ;; 4--> 26 r51=[r47+r50] :rice_load,nothing ;; 5--> 31 R0=r50+0x24 :nothing ;; 6--> 27 [const(`common_reg'+0x45)]=r51 :nothing ;; 7--> 33 r54=[r47+R0] :rice_load,nothing ;; 8--> 38 R0=r50+0x48 :nothing ;; 9--> 34 [const(`common_reg'+0x49)]=r54 :nothing ;; 10--> 40 r57=[r47+R0] :rice_load,nothing ;; 11--> 45 R0=r50+0x6c :nothing ;; 12--> 41 [const(`common_reg'+0x4b)]=r57 :nothing ;; 13--> 47 r60=[r47+R0] :rice_load,nothing ;; 14--> 52 R0=r50+0x90 :nothing ;; 15--> 48 [const(`common_reg'+0x4f)]=r60 :nothing ;; 16--> 54 r63=[r47+R0] :rice_load,nothing ;; 17--> 57 R0=r50+0xb4 :nothing ;; 18--> 55 [const(`common_reg'+0x53)]=r63 :nothing ;; 19--> 59 r43=r47+R0 :nothing ;; 20--> 62 r66=[r43] :rice_load,nothing ;; 21--> 69 R0=`common_reg' :nothing ;; 22--> 63 [const(`common_reg'+0x55)]=r66 :nothing ;; 23--> 67 r68=[r43] :rice_load,nothing ;; 24--> 70 r46=R0 :nothing ;; 25--> 68 [const(`common_reg'+0x57)]=r68 :nothing The C source, "common_reg" "DiffReg" are globel unsigned char arrays, iFrequency is a globel unsigned char variable : int i = 0; BYTE* pDiffPair = common_reg + (COMMON_REG_WRITE << 1), *pData = DiffReg; *(pDiffPair + 1) = *(pData + iFrequency); pData = pData + 36; *(pDiffPair + 5) = *(pData + iFrequency); pData = pData + 36; *(pDiffPair + 7) = *(pData + iFrequency); pData = pData + 36; *(pDiffPair + 11) = *(pData + iFrequency); pData = pData + 36; *(pDiffPair + 15) = *(pData + iFrequency); pData = pData + 36; *(pDiffPair + 17) = *(pData + iFrequency); *(pDiffPair + 19) = *(pData + iFrequency); Thank you very much for your guys advices! Danie.Tian