On 20 Nov 09:49, Uros Bizjak wrote: > On Tue, Nov 19, 2013 at 9:43 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. > > Uros.
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. Thanks, Ilya -- gcc/ 2013-11-19 Ilya Enkovich <ilya.enkov...@intel.com> * config/i386/i386.md (UNSPEC_SIZEOF): New. (move_size_reloc_<mode>): New. * config/i386/predicates.md (symbol_operand): New. diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraints.md index 7289ae4..b29fadb 100644 --- a/gcc/config/i386/constraints.md +++ b/gcc/config/i386/constraints.md @@ -241,6 +241,7 @@ ;; s - address with no segment register ;; i - address with no index and no rip ;; b - address with no base and no rip +;; S - symbol reference (define_address_constraint "Tv" "VSIB address operand" diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index e23b3b6..772c09d 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -79,6 +79,7 @@ UNSPEC_PLTOFF UNSPEC_MACHOPIC_OFFSET UNSPEC_PCREL + UNSPEC_SIZEOF ;; Prologue support UNSPEC_STACK_ALLOC @@ -18446,6 +18447,22 @@ "bndstx\t{%2, %3|%3, %2}" [(set_attr "type" "mpxst")]) +(define_insn "move_size_reloc_<mode>" + [(set (match_operand:SWI48 0 "register_operand" "=r") + (unspec:<MODE> + [(match_operand:<MODE> 1 "symbol_operand")] + UNSPEC_SIZEOF))] + "" +{ + if (GET_MODE (operands[0]) == SImode) + return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}"; + else if (x86_64_zext_immediate_operand (operands[1], VOIDmode) + || ix86_cmodel == CM_KERNEL) + return "mov{q}\t{%1@SIZE, %0|%0, %1@SIZE}"; + else + return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}"; +}) + (include "mmx.md") (include "sse.md") (include "sync.md") diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md index 66ac52f..5c758ab 100644 --- a/gcc/config/i386/predicates.md +++ b/gcc/config/i386/predicates.md @@ -119,6 +119,10 @@ (match_test "TARGET_64BIT") (match_test "REGNO (op) > BX_REG"))) +;; Return true if VALUE is symbol reference +(define_predicate "symbol_operand" + (match_code "symbol_ref")) + ;; Return true if VALUE can be stored in a sign extended immediate field. (define_predicate "x86_64_immediate_operand" (match_code "const_int,symbol_ref,label_ref,const")