2013/11/20 Ilya Enkovich <enkovich....@gmail.com>: > 2013/11/20 Uros Bizjak <ubiz...@gmail.com>: >> On Wed, Nov 20, 2013 at 5:11 PM, Ilya Enkovich <enkovich....@gmail.com> >> wrote: >>> 2013/11/20 Uros Bizjak <ubiz...@gmail.com>: >>>> On Wed, Nov 20, 2013 at 1:32 PM, Ilya Enkovich <enkovich....@gmail.com> >>>> wrote: >>>> >>>>>> >> > Here is a patch to add size relocation and instruction to obtain >>>>>> >> > object's size in i386 target. >>>>>> >> >>>>>> >> +(define_insn "move_size_reloc_<mode>" >>>>>> >> + [(set (match_operand:SWI48 0 "register_operand" "=r") >>>>>> >> + (match_operand:<MODE> 1 "size_relocation" "Z"))] >>>>>> >> + "" >>>>>> >> +{ >>>>>> >> + return "mov{<imodesuffix>}\t{%1, %0|%0, %1}"; >>>>>> >> >>>>>> >> Please don't change x86_64_immediate_operand just to use "Z" >>>>>> >> constraint The predicate is used in a couple of other places that for >>>>>> >> sure don't accept your change. >>>>>> >> >>>>>> >> Better write this insn in an explicit way (see for example >>>>>> >> tls_initial_exec_64_sun). Something like: >>>>>> >> >>>>>> >> (define_insn "move_size_reloc_<mode>" >>>>>> >> [(set (match_operand:SWI48 0 "register_operand" "=r") >>>>>> >> (unspec:SWI48 >>>>>> >> [(match_operand 1 "symbolic_operand" "..." )] >>>>>> >> UNSPEC_SIZEOF))] >>>>>> >> "" >>>>>> >> "mov{<imodesuffix>}\t{%a1@SIZE, %0|%0, %a1@SIZE}") >>>>>> >> >>>>>> >> You will probably need to define new operand 1 predicate and >>>>>> >> constraint. >>>>>> >> >>>>>> >> Uros. >>>>>> > >>>>>> > Hi, Uros! Thanks for comments! Here is what I got trying to follow >>>>>> > your suggestion. Does it look better? >>>>>> >>>>>> You actually don't need any operand modifiers in the insn template. >>>>>> Simply use: >>>>>> >>>>>> "mov{<imodesuffix>}\t{%1@SIZE, %0|%0, %1@SIZE}" >>>>>> >>>>>> and you will automatically get >>>>>> >>>>>> "movl $zzz, %eax" or "mov %eax, OFFSET FLAT: zzz". >>>>>> >>>>>> Since your pattern allows only symbolic_operand, there is no reload, >>>>>> so you can avoid the constraint alltogether. >>>>>> >>>>>> BTW: Did you consider various -mcmodel=... options? For DImode moves, >>>>>> you should check x86_64_zext_immediate_operand predicate and output >>>>>> either "movl $zzz, %eax" or "movabs $zzz, %rax". There is no movq with >>>>>> 64bit immediate. Please see movdi pattern. >>>>> >>>>> Yep, for large objects it may work wrongly. Does anyone use static >>>>> objects >4Gb? :) >>>>> >>>>> Large address does not mean large object but seems we have to be >>>>> conservative here. I added x86_64_zext_immediate_operand check with >>>>> additional CM_KERNEL check because in this model object size should >>>>> always fit 32 bits. >>>> >>>> IMO, we should list code models that support object sizes > 31bits for >>>> 64bit target. The object size in small models will never be > 31bits >>>> (and never negative), so we can use movl unconditionally. >>> >>> For medium models x86_64_zext_immediate_operand returns true for >>> object is known to go to lower 2Gb space. It should allow us to use >>> movl. Why do you always emit movabs for medium model? >> >> CM_MEDIUM has unlimited data size. >> >> i386-opts.h: CM_MEDIUM, /* Assumes code fits in the low 31 >> bits; data unlimited. */ >> >> The x86_64_zext_immediate_operand allows _address_ to be loaded by >> movl. The @SIZE reloc returns object size, which is unlimited and has >> no connection to its address. For CM_MEDIUM, >> x86_64_zext_immediate_operand allows: >> >> return (ix86_cmodel == CM_SMALL >> || (ix86_cmodel == CM_MEDIUM >> && !SYMBOL_REF_FAR_ADDR_P (op))); > > Yes, but large symbols never have SYMBOL_FLAG_FAR_ADDR set.
Sorry, I mean all large symbols have this flag set. > > Ilya > >> >> Uros.