Nios2 arch=r1/r2

2016-03-09 Thread BELBACHIR Selim
Hi,

I'm looking at gcc-nios2 options -march.
It seems two instruction sets can be selected (r1/r2) but I cannot find out 
where theses instructions set are described.
On the other end I found this document 
https://www.altera.com/content/dam/altera-www/global/en_US/pdfs/literature/hb/nios2/n2cpu_nii51017.pdf
 which describes several updates of the instruction set (section Document 
Revision History) from 2004 to 2015.

I'm looking for a recent gcc-nios2 compiler compatible pour nios2 version 6.1 
(November 2006) i.e. without the 'jmpi' instruction.

Do I have to modify the backend to add a -mno-jmpi option ?

  Regards,

Selim



RE: try_merge_delay_insn with delay list > 1

2015-04-21 Thread BELBACHIR Selim
Great, I'll read more closely formatting rules next time I'll submit something.

Regards,

Selim


-Message d'origine-
De : Jeff Law [mailto:l...@redhat.com] 
Envoyé : lundi 20 avril 2015 19:47
À : BELBACHIR Selim; gcc@gcc.gnu.org
Objet : Re: try_merge_delay_insn with delay list > 1

On 04/20/2015 05:08 AM, BELBACHIR Selim wrote:
> I've attached the fixed version of the patch. I've tested it on the trunk 
> with my private target.
>
> I can't provide a test because apparently no backend (other than my private 
> one) uses delay slots with more that 1 slot.
> I was also unable to test the behaviour of this patch for an hypothetic 
> target providing delay lots with more that 1 slot AND the possibility to 
> annul instruction in delay slots.
>
> It seems to me that this patch is a small enhancement anyway.
> I hope it's ok for trunk :)
Even for small enhancements or bugfixes, we try to at least do some basic 
testing.  Unfortunately with no sparc or mips machines in the compile farm, 
good testing of a reorg.c change is hard.

I built mips-elf cross tools and used those to compile newlib for mips-elf.  
Then I applied your patch, rebuilt the compiler and used that to compile newlib 
again.  Then I compared all the objects from the two copies of newlib and 
verified the code we generated as identical.  So there's at least some degree 
of confidence we didn't mess anything up in the single delay slot case.

I fixed a couple more minor formatting problems and installed your change on 
the trunk.

jeff




RE: try_merge_delay_insn with delay list > 1

2015-04-20 Thread BELBACHIR Selim
I've attached the fixed version of the patch. I've tested it on the trunk with 
my private target.

I can't provide a test because apparently no backend (other than my private 
one) uses delay slots with more that 1 slot.
I was also unable to test the behaviour of this patch for an hypothetic target 
providing delay lots with more that 1 slot AND the possibility to annul 
instruction in delay slots.

It seems to me that this patch is a small enhancement anyway.
I hope it's ok for trunk :)

Regards,

Selim

-Message d'origine-
De : Jeff Law [mailto:l...@redhat.com] 
Envoyé : vendredi 17 avril 2015 18:41
À : BELBACHIR Selim; gcc@gcc.gnu.org
Objet : Re: try_merge_delay_insn with delay list > 1

On 03/10/2015 07:40 AM, BELBACHIR Selim wrote:
> Me again :)
>
> I enhanced my patch because it was not generalized for instructions with N 
> delay_slots.
Mostly OK, though there are some formatting nits that need to be corrected.

We have whitespace around arithmetic, logical and comparison operators to 
separate them from their operands.  So instead of

slot_number+j

Use

slot_number + j

Instead of

j=1

Use

j = 1

Lines should be wrapped at 80 columns.  So you end up with something like this

foo (argument1,
  argument2,
  argument3)

ie, when you wrap, the arguments to the call will line up vertically.

It may help wrapping to create a local variable to hold PATTERN (insn). 
  Call it 'pat' :-)

When referring to variables or parameters in a comment, capitalize them.

The patch may need updating for the trunk, please test it with the trunk when 
you ask  for it to be included on the trunk.

These are all fairly minor issues.  The actual change seems reasonable.

What systems do you have that you could do a bootstrap and regression test 
with?  Ideally since you're changing the delay slot branching code it'd be a 
system with delay slots :-)  If that's not possible because you don't have 
access to a bootstrapping system with delay slots, make sure to mention it.

Ideally you'd have a test for this bug. However, with a private port I wouldn't 
consider it a necessity.  However, you may want to go ahead and create one for 
internal uses.  And if you ever submit your port to the offficial sources, you 
can include target specific tests at that time.




try_merge_patch3
Description: try_merge_patch3


RE: try_merge_delay_insn with delay list > 1

2015-03-10 Thread BELBACHIR Selim
Me again :)

I enhanced my patch because it was not generalized for instructions with N 
delay_slots.

Selim


try_merge_patch2
Description: try_merge_patch2


try_merge_delay_insn with delay list > 1

2015-03-10 Thread BELBACHIR Selim
Hi,

I'm still working on a private backend on gcc 4.9.2. My processor provides 
instructions with 2 delay slots. I'm well aware that this feature is very 
uncommon and not fully tested. Nevertheless I submit the problem and the 
solution I've found.

The bug is located in the function try_merge_delay_insns(INSN, THREAD) in 
reorg.c. In there, gcc " tries to merge insns starting at THREAD which match 
exactly the insns in INSN's delay list ".


Suppose INSN is a 'delayed jump' filled with 2 delayed insns :

jmp_if_EQ_delayed .L1  # jump to L1 if condition code indicates equality
   mov r1, r2
   mov r3, mem(r1++)  # move r0 in memory pointed by r6 and post 
increment r6


and TARGET is a 'delayed jump if zero' filled with 1 delayed insn :

jmpz_delayed  --r7, L2# decrement r7 and jump L2 if r7 == 0
   mov r1, r2


The current implementation of try_merge_delay_insns(INSN, THREAD) will delete 
'mov r1,r2' from the delay slot of TARGET because it matches the 'mov r1,r2' 
inside INSN delay list. No check verifies that r1 has changed between the 2 
'mov r1,r2' insns.

I attached a patch that tries to solve this problem.

   Regards,

Selim




try_merge_patch
Description: try_merge_patch


bug in lra-constraints.c (simple_move_p register_move_cost)

2014-12-16 Thread BELBACHIR Selim
Hi,

I may have found a bug when I was trying to port my private backend to new LRA 
pass (using gcc 4.9.2+patches).

In lra-constraints.c, in function simple_move_p, the target hook 
targetm.register_move_cost is called with two badly swapped parameters :

targetm.register_move_cost (GET_MODE (src), sclass, dclass) 

should be :

targetm.register_move_cost (GET_MODE (src), dclass, sclass)


In my port of GCC it leads to an error when checking constrain_operands at the 
end of LRA pass

   Regards,

Selim Belbachir









g++.dg/lto/lto.exp bug

2014-07-10 Thread BELBACHIR Selim
Hi,

In gcc 4.7.3 I found a bug in the testsuite script g++.dg/lto/lto.exp when a 
target does not support LTO (ENABLE_LTO not defined)

The following lines :

if { ![check_effective_target_lto] } {
return
}

Should be called before :

g++_init
lto_init no-mathlib


(Like in gcc.dg/lto/lto.exp)


Otherwise 'lto_init' may hack board_info (removing the mathlib option) without 
being restored by 'lto_finish' because of the brutal return after 
'check_effective_target_lto'


Selim


RE: implicit gnat_malloc seen as vararg function

2014-06-11 Thread BELBACHIR Selim
Hi,

I have more info concerning my gnat_malloc problem.

I watched the code in gcc/ada/gcc-interface/trans.c and found the location 
where malloc_decl tree is built.
In gigi ()function (trans.c:411), the ftype for malloc_decl is done this way :

  ftype = build_function_type_list (ptr_void_type_node, sizetype, NULL_TREE);

I looked at the code of build_function_type_list_1 in tree.c and found that 
stdargs function are built with their chained list of argument ending with a 
void_list_node :

{
  last = args;
  args = nreverse (args);
  TREE_CHAIN (last) = void_list_node;
}

But I also noticed that void_list_node was a null pointer!! instead of being a 
node with TREE_VALUE = void_type_node and no TREE_CHAIN  (as described in 
tree.h)
So I wondered, where should void_list_node be initialized in GNAT frontend and 
noticed that the initialization of void_list_node was done AFTER its use to 
declare ftype for malloc_decl.

ftype  for malloc_decl is initialized in gigi() function at trans.c:411  
whereas void_list_node in only initialized in gigi() function at trans.c:665 by 
a call to gnat_install_builtins() ---> install_builtin_elementary_types()  --> 
void_list_node = build_void_list_node ();


It seems like a bug. Is it a known one ? someone has the proper fix ? I put the 
call to gnat_install_builtins() higher inside gigi() and it solve my current 
problem but I'm not sure exactly when it has to be called and if there are bad 
side effects.

Regards,

Selim Belbachir




implicit gnat_malloc seen as vararg function

2014-06-10 Thread BELBACHIR Selim
Hi,

I'm working on a private port of GCC 4.7.3/GNAT 7.1.2.

Calls to ADA 'new' operator generates implicit gnat_malloc(size) calls (which 
has to be provided by user program or runtime).

In my macro INIT_CUMULATIVE_ARGS I noticed that gnat_malloc(size) calls are 
seen as vararg function because the tree.c function stdarg_p(fntype) returns 
true. This creates bad code because caller put the argument in stack (this is 
normal behaviour for my vararg functions) whereas the callee expected argument 
in register (gnat_malloc signature should only contains the 'size'  argument of 
type size_type).

microblaze and iq2000 backend should have the same problem because inside 
INIT_CUMULATIVE_ARGS macro, variable argument function are identified by 
browsing fntype tree chain (like stdarg_p does)

Do I have to fix the GNAT frontend or did I missed an option dealing with 
gnat_malloc behaviour ?

Regards,

   Selim Belbachir


RE: gnat.dg test: div_no_warning.adb

2014-06-06 Thread BELBACHIR Selim
Hi,

I've noticed that Constraint_error warning produced by 
gcc/testsuite/gnat.dg/div_no_warning.adb disappears if the target runtime 
contains :

"Configurable_Run_Time : constant Boolean := False;"


* x86 native gnat contains Configurable_Run_Time := False ==> no warning
* Cross gnat port without full runtime contains Configurable_Run_Time := True  
==> warning raised


When I read the description of "Configurable_Run_Time_On_Target : Boolean := 
False;" in gcc/ada/targparm.ads (which may not be complete) I don't see any 
relation with this particular constraint error raising.

Can someone explain what are the full impact of Configurable_Run_Time boolean 
in system.ads and what is the relation between it and the "constant folding for 
short-circuit control forms" tested by gcc/testsuite/gnat.dg/div_no_warning.adb 
?

Regards,

Selim






RE: Gimplilfy ICE in gnat.dg/array18.adb

2014-06-06 Thread BELBACHIR Selim
The intent of the patch change is clear. 

The strange thing concern the variable "A" declared this way "A : String (1 .. 
1);", used that way "A := F;"  and displayed in tree (gnu_target) as a 
RECORD_TYPE instead of an ARRAY_TYPE.


The test to know if a temporary for return value is needed only check 
ARRAY_RANGE_REF and ARRAY_TYPE and not RECORD_TYPE :

TREE_CODE (gnu_target) == ARRAY_RANGE_REF
||
(TREE_CODE (TREE_TYPE (gnu_target)) == ARRAY_TYPE
&& TREE_CODE (TYPE_SIZE (TREE_TYPE (gnu_target)))  == INTEGER_CST)


I don't why in my case fixed Strings are RECORD_TYPE and not ARRAY_TYPE. 
Maybe its normal and I should extend the if condition with RECORD_TYPE :

TREE_CODE (gnu_target) == ARRAY_RANGE_REF
||
(TREE_CODE (TREE_TYPE (gnu_target)) == ARRAY_TYPE
&& TREE_CODE (TYPE_SIZE (TREE_TYPE (gnu_target)))  == INTEGER_CST)
||
(TREE_CODE (TREE_TYPE (gnu_target)) == RECORD_TYPE
&& TREE_CODE (TYPE_SIZE (TREE_TYPE (gnu_target)))  == INTEGER_CST)


-Message d'origine-
De : gcc-ow...@gcc.gnu.org [mailto:gcc-ow...@gcc.gnu.org] De la part de Eric 
Botcazou
Envoyé : vendredi 6 juin 2014 10:20
À : BELBACHIR Selim
Cc : gcc@gcc.gnu.org
Objet : Re: Gimplilfy ICE in gnat.dg/array18.adb

> strangely my var_decl for 'a' is a record and not an array_type so the 'if'
> condition is false (and true on X86_64) I looked for somewhere in 
> my backend something that would transform an array_type into a 
> record_type but I did not find anything.

The comment should clearly state the intent of the change though and how to 
adjust it to your needs.

--
Eric Botcazou


RE: Gimplilfy ICE in gnat.dg/array18.adb

2014-06-06 Thread BELBACHIR Selim
   arg 0 
readonly visited
arg 0 
readonly visited arg 0 >>> arg 1 > unit size 
align 8 symtab 0 alias set 0 canonical type 0x2ad27c8ee498
domain  unit size 
align 64 symtab 0 alias set -1 canonical type 0x2ad27c79a000 
precision 64 min  max >
sizes-gimplified visited DI size  unit 
size 
align 64 symtab 0 alias set -1 canonical type 0x2ad27c8ee3f0 precision 
64 min  max 
index type 
sizes-gimplified public visited unsigned SI
size 
unit size 
align 32 symtab 0 alias set 0 canonical type 0x2ad27c8ee150 
precision 32 min  max  context  RM size 
 RM min  RM max 

chain >
chain > context 
chain >

There are also differenced in the gnu_result_type I cannot explain ...





-Message d'origine-
De : Eric Botcazou [mailto:ebotca...@adacore.com] 
Envoyé : vendredi 6 juin 2014 00:00
À : BELBACHIR Selim
Cc : gcc@gcc.gnu.org
Objet : Re: Gimplilfy ICE in gnat.dg/array18.adb

> Can someone give me a hint to solve my problem ? I have no idea which 
> part of my backend could be related to the GENERIC or GIMPLE 
> generation and I'm very unfamiliar with this part of GCC.

Look at the patch installed in conjunction with gnat.dg/array18.adb.

--
Eric Botcazou


Gimplilfy ICE in gnat.dg/array18.adb

2014-06-05 Thread BELBACHIR Selim
Hi,

On my private port, I'm unable to debug an ICE on GCC4.7.3 (GNAT 7.1.2) during 
the internal test testsuite/gnat.dg/array18.adb.

Here is the test source code:
-
with Array18_Pkg; use Array18_Pkg;

procedure Array18 is
   A : String (1 .. 1);
begin
   A := F;
end;
-
-
package Array18_Pkg is

   function N return Positive;

   subtype S is String (1 .. N);

   function F return S;

end Array18_Pkg;
-

The size of the String returned by 'F' can't be known at compile time. GNAT 
will compare the size of the returned string to the size of 'A' at runtime (to 
call last_chance_handler or not).


The ICE is an assert inside force_constant_size of gimplify.c (at line 717)  :
---
static void
force_constant_size (tree var)
{
  /* The only attempt we make is by querying the maximum size of objects
 of the variable's type.  */

  HOST_WIDE_INT max_size;

  gcc_assert (TREE_CODE (var) == VAR_DECL);

  max_size = max_int_size_in_bytes (TREE_TYPE (var));

  gcc_assert (max_size >= 0); 
max_size = -1 !!

  DECL_SIZE_UNIT (var)
= build_int_cst (TREE_TYPE (DECL_SIZE_UNIT (var)), max_size);
  DECL_SIZE (var)
= build_int_cst (TREE_TYPE (DECL_SIZE (var)), max_size * BITS_PER_UNIT);
}
---

The 'var' parameter contains  :
---
 
unit size 
align 8 symtab 0 alias set -1 canonical type 0x2ab02348 
precision 8 min  max  context 
pointer_to_this >
sizes-gimplified visited nonaliased-component BLK
size 
readonly visited
arg 0 
readonly visited arg 0 > arg 1 >
unit size 
readonly visited arg 0 >
align 8 symtab 0 alias set 0 canonical type 0x2abb2f18
domain 
sizes-gimplified visited SI
size 
unit size 
align 32 symtab 0 alias set -1 canonical type 0x2abb2e70 
precision 32 min  max  
index type 
chain > context 

chain >
used ignored BLK file 
/vues_statiques/FPGA/belbachir/prism/compiler/gcc_test/internal/../../gcc/gcc/testsuite/gnat.dg/array18.adb
 line 9 col 9 size  unit size 
align 8>
---



I used -fdump-tree-all option and run my cross compiler and the native x86_64 
compiler (same GCC/GNAT version) to compare the dumps

I don't have the same results event in the first dump :

>> X86_64 array18.adb.003t.original :
--
Array18 ()
{
  typedef array18__TTaSP1___XDLU_1__1 array18__TTaSP1___XDLU_1__1;
  typedef  struct ;
  typedef character array18__TaS[1:1];
  character a[1:1];
  character R.0[1:(sizetype) (integer) array18_pkg__R1s];

typedef array18__TTaSP1___XDLU_1__1 array18__TTaSP1___XDLU_1__1;
typedef  struct ;
typedef character array18__TaS[1:1];
character a[1:1];
  if (array18_pkg__R1s != 1)
{
  .gnat_last_chance_handler ("array18.adb", 9);
}
  else
{

}
character R.0[1:(sizetype) (integer) array18_pkg__R1s];
  R.0 = array18_pkg.f ();
  a = VIEW_CONVERT_EXPR(R.0);
  return;
}


_GLOBAL.SZ0.ada_array18 (integer p0, integer p1)
{
  return p1 <= p0 ? (bitsizetype) sizetype) p0 - (sizetype) p1) + 1) * 8) : 
0;


_GLOBAL.SZ1.ada_array18 (integer p0, integer p1)
{
  return p1 <= p0 ? ((sizetype) p0 - (sizetype) p1) + 1 : 0;
--


>> MyPort  array18.adb.003t.original :
--
Array18 ()
{
  typedef array18__TTaSP1___XDLU_1__1 array18__TTaSP1___XDLU_1__1;
  typedef  struct ;
  typedef character array18__TaS[1:1];
  typedef struct array18__a___PAD array18__a___PAD;
  struct array18__a___PAD a;

typedef array18__TTaSP1___XDLU_1__1 array18__TTaSP1___XDLU_1__1;
typedef  struct ;
typedef character array18__TaS[1:1];
typedef struct array18__a___PAD array18__a___PAD;
struct array18__a___PAD a;
  if (array18_pkg__R1s != 1)
{
  .gnat_last_chance_handler ("array18.adb", 9);
}
  else
{

}
  a = {.F=VIEW_CONVERT_EXPR(array18_pkg.f ())};
  return;
}


_GLOBAL.SZ0.ada_array18 (integer p0, integer p1)
{
  return p1 <= p0 ? ((bitsizetype) ((sizetype) p0 - (sizetype) p1) + 1) * 8 : 0;


_GLOBAL.SZ1.ada_array18 (integer p0, integer p1)
{
  return p1 <= p0 ? ((sizetype) p0 - (sizetype) p1) + 1 : 0;
--



The next 004t.gimple dump is incomplete since the ICE is during gimplify pass.


Using debugger I saw that the X86_64 port never goes inside force_constant_size 
(where is located the ICE on my port)...

Can someone give me a hint to solve my problem ? I have no idea which part of 
my backend could be related to the GENERIC or GIMPLE generation and I'm very 
unfamiliar with this part of GCC.


Regards,


Selim Belbachir







LTO + conditional jump + delay slot

2014-04-30 Thread BELBACHIR Selim
Hi,

I encountered a problem on test 'gcc.c-torture/execute/loop-7.c' (gcc4.7.3) on 
my private port during test case "-O2 -flto -fuse-linker-plugin 
-fno-fat-lto-objects"

Here is the tested code :

void foo (unsigned int n)
{
  int i, j = -1;

  for (i = 0; i < 10 && j < 0; i++)
{
  if ((1UL << i) == n)
j = i;
}

  if (j < 0)
abort ();
}

main()
{
  foo (64);
  exit (0);
}


The LTO option merge the foo  function into the main function. 

I'll try present my problem by simplifying the resulting assembler.

:
:L1
[...]  << content of the loop
compare 0, $R0  << test to know if the loop goes on or stop 
($R0 synthetize the whole loop end condition) 
jump_delayed.ifNE L1 << conditional delayed jump : the loop end if $R0 
== 0
nop #delayslot1
sll $R1, 1, $R0 #delayslot2  << instruction which is part of the loop content 
but placed into the 2nd delay slot of jump_delayed.ifNE instruction
compare -1, $R2 << test if (j < 0)
branch.ifeq abort<< conditional branch to abort
branch exit  << branch to exit which expect a 0 into 
$R0 as first parameter

The test fail, not because abort is called, but because exit is called with $R0 
containing 0x80 and not 0.
I think GCC expect $R0 to be equal to 0 when the loop end (so no need to set 
explicitly $R0 to 0)
But in this case the 'sll' instruction placed into the delay slot of the 
conditional delayed jump modify $R0 even if no jump is performed.

Is it a bug due to LTO merging the 'foo' and 'main' function ?

Or does GCC really thinks that the instructions placed into the delay slot of 
conditional jump are executed only if the condition is true ?

Or is it simply a GCC incompatibility between 'conditional jump' & 'delay 
slots' ?



Here are some parts of my backend relative to delay slot and conditional jump 
(nothing formidable :) ):

(define_delay (ior (eq_attr "type" "jump") (eq_attr "type" "cond_jump"))
  [(and (eq_attr "delayable" "yes") (eq_attr "length" "1")) (nil) (nil)
   (and (eq_attr "delayable" "yes") (eq_attr "length" "1")) (nil) (nil)])

(define_insn "jumpif"
  [(set (pc)
(if_then_else (match_operator 0 "comparison_operator"
  [(match_operand 2 "cc_register" "") (const_int 0)])
(label_ref (match_operand 1 "" ""))
(pc)))]
  ""
  { [...] // use final_sequence to detect delay slot }
  [set_attr "type" "cond_jump")
   (set_attr "delayable" "no")]


Regards,

Selim







wrong assertion in caller-save.c

2014-01-10 Thread BELBACHIR Selim
Hi,

I think I found a bug in gcc 4.7.3 in gcc/caller-save.c at line 158 : 

 gcc_assert (cached_reg_save_code[reg][mode]);

should be :

 gcc_assert (cached_reg_save_code[reg][mode] != -1);

because cached_reg_save_code contains INSN_CODES that can be equal to 0 (see 
attached patch)


In my backend movdi pattern has unfortunately code '0' (depends on pattern 
declaration order).
When gcc tried to determine if my DI regs can be saved and restore as 'caller 
saves' (in caller-save.c::init_caller_save()) it failed on this wrong assertion.


Regards,

Selim


caller-save.patch
Description: caller-save.patch


lto testsuite may erase mathlib variable

2014-01-03 Thread BELBACHIR Selim
Hi,

I noticed a problem in gcc/testsuite/g++.dg/lto/lto.exp

If the target does not support LTO (check_effective_target_lto) a brutal return 
is performed so the mathlib variable modified in lto_init will not be restored 
properly by lto_finish at the end of the script.

Subsequent testsuites will found an empty mathlib.

Regards,

Selim




patch
Description: patch


Why __builtin_sqrt do not totally replace sqrt in asm

2014-01-03 Thread BELBACHIR Selim
Hi,

When the standard pattern 'sqrtm2' is defined I don't understand why calls to 
sqrt or __builtin_sqrt is always followed by a comparison of the result with 
itself (checking the NaN ?) and a conditional branch to sqrt symbol (so linking 
with libm is always mandatory).

-
mov $FP0,$FP1
fsqrt $FP0, $FP0<< the builtin_sqrt
fcompare $FP0,$FP0 << strange compare of the result of builtin_sqrt
jmp.ifEQUAL .L2
mov $FP1,$FP0
branch sqrt<< branch to sqrt symbol if $FP0 != $FP0
.L2
-

Is there a way to tell GCC that sqrt function is totally handled by 
__builtin_sqrt ?

Regards,

Selim





RE: cpp0x test suite PASS/FAIL

2013-12-11 Thread BELBACHIR Selim
I found a potential problem in "dejagnu-1.5.1/lib/framework.exp"  (or previous 
version)

As I said before, in my case, the selector 'target std=c++98' doesn't seems to 
prevent the FAIL when -std=c++11 options is used in compiler flags.
I noticed that -std=c++11 is my last compiler flag and in function 
"check_conditional_xfail" from dejagnu-1.5.1/lib/framework.exp (called by 
check-flags from gcc-4.7.3/gcc/testsuite/lib/target-supports-dg.exp) I saw the 
following lines :

verbose "Looking for $opt to exclude in the compiler flags" 2
foreach j "$opt" {
if {[string match "* $j *" $compiler_flags]} {
verbose "Found $j to exclude in the compiler flags" 2
incr excl_hit
}
}

'string match' uses "* $j *" , i.e. a white space is required after each option 
in order to be properly matched. When an option is the last compiler flag then 
it cannot be matched because it is not followed by a white space. This explains 
why the dg-error is not ignored when compiler with -std=c++11 even if selector 
'target c++98' is used.

I may be the only one to meet this exact problem because for some reasons 
-std=c++xx options is my last flag AND some tests use a selector on this 
particular flag. But, imho the problem can be met on any other flag as far as 
it is the last compiler flag.

Answer : (a) bug in the test harness code 

Am I right ?


Selim

-Message d'origine-
De : Joseph Myers [mailto:jos...@codesourcery.com] 
Envoyé : mardi 10 décembre 2013 18:57
À : BELBACHIR Selim
Cc : gcc@gcc.gnu.org
Objet : RE: cpp0x test suite PASS/FAIL

On Tue, 10 Dec 2013, BELBACHIR Selim wrote:

> The selector 'target c++98' (in { dg-error "std=" "std" { target c++98 
> } } for example) do not prevent the FAIL to be printed when -std=c++11 
> options is used.

Well, that would be a bug in one of (a) the test harness code, (b) the way the 
selector is used, (c) your DejaGnu installation.  In none of those cases is 
ignoring the FAIL appropriate; both (a) and (c) could well cause other problems 
with inaccurate test results elsewhere in the testsuite.  
You'll need to investigate why DejaGnu isn't behaving as intended on your 
system.

-- 
Joseph S. Myers
jos...@codesourcery.com


RE: cpp0x test suite PASS/FAIL

2013-12-11 Thread BELBACHIR Selim
Ok so it's a problem local to my environment that I must fix. I've downloaded 
the lastest dejagnu 1.5.1 but it doesn't solve the problem. 
I found in no documentation the selector 'target c++98' but it should exist 
somewhere because about 20 c++11 tests use it and FAIL the same way.
I'll try to investigate further (tcl is a pain for me :) )

Selim

-Message d'origine-
De : Joseph Myers [mailto:jos...@codesourcery.com] 
Envoyé : mardi 10 décembre 2013 18:57
À : BELBACHIR Selim
Cc : gcc@gcc.gnu.org
Objet : RE: cpp0x test suite PASS/FAIL

On Tue, 10 Dec 2013, BELBACHIR Selim wrote:

> The selector 'target c++98' (in { dg-error "std=" "std" { target c++98 
> } } for example) do not prevent the FAIL to be printed when -std=c++11 
> options is used.

Well, that would be a bug in one of (a) the test harness code, (b) the way the 
selector is used, (c) your DejaGnu installation.  In none of those cases is 
ignoring the FAIL appropriate; both (a) and (c) could well cause other problems 
with inaccurate test results elsewhere in the testsuite.  
You'll need to investigate why DejaGnu isn't behaving as intended on your 
system.

-- 
Joseph S. Myers
jos...@codesourcery.com


RE: cpp0x test suite PASS/FAIL

2013-12-10 Thread BELBACHIR Selim
I have exactly the same behaviour than my native linux compiler. I don't 
understand why DejaGnu exp files print such FAIL.

3 errors has to be printed when using -std=c++98 and 0 errors has to be printed 
when using -std=c++11. That's what my compiler does.

The selector 'target c++98' (in { dg-error "std=" "std" { target c++98 } }  for 
example) do not prevent the FAIL to be printed when -std=c++11 options is used.
Only the last 'test for excess errors' seems to understand that no errors has 
to be printed when using -std=c++11


Here is the DejaGnu log :

Running  gcc-4.7.3/gcc/testsuite/g++.dg/dg.exp ...
ALWAYS_CXXFLAGS set to additional_flags= ldflags= 
additional_flags=-fmessage-length=0
Executing on host:  prism-g++ gcc-4.7.3/gcc/testsuite/g++.dg/cpp0x/auto27.C   
-fmessage-length=0 -std=c++98  -pedantic-errors -Wno-long-long  -S -o auto27.s  
  (timeout = 300)
gcc-4.7.3/gcc/testsuite/g++.dg/cpp0x/auto27.C:3:14: error: ISO C++ forbids 
declaration of 'main' with no type [-pedantic]
gcc-4.7.3/gcc/testsuite/g++.dg/cpp0x/auto27.C:3:14: error: top-level 
declaration of 'main' specifies 'auto'
gcc-4.7.3/gcc/testsuite/g++.dg/cpp0x/auto27.C:3:14: error: trailing return type 
only available with -std=c++11 or -std=gnu++11
compiler exited with status 1
output is:
gcc-4.7.3/gcc/testsuite/g++.dg/cpp0x/auto27.C:3:14: error: ISO C++ forbids 
declaration of 'main' with no type [-pedantic]
gcc-4.7.3/gcc/testsuite/g++.dg/cpp0x/auto27.C:3:14: error: top-level 
declaration of 'main' specifies 'auto'
gcc-4.7.3/gcc/testsuite/g++.dg/cpp0x/auto27.C:3:14: error: trailing return type 
only available with -std=c++11 or -std=gnu++11
PASS: g++.dg/cpp0x/auto27.C -std=c++98 std (test for errors, line 3)
PASS: g++.dg/cpp0x/auto27.C -std=c++98 auto (test for errors, line 3)
PASS: g++.dg/cpp0x/auto27.C -std=c++98 no type (test for errors, line 3)
PASS: g++.dg/cpp0x/auto27.C -std=c++98 (test for excess errors)
Executing on host: prism-g++ gcc-4.7.3/gcc/testsuite/g++.dg/cpp0x/auto27.C   
-fmessage-length=0 -std=c++11  -pedantic-errors -Wno-long-long  -S 
-DSIGNAL_SUPPRESS -DNO_TRAMPOLINES -DSTACK_SIZE=0x4800 -o auto27.s(timeout 
= 300)
FAIL: g++.dg/cpp0x/auto27.C -std=c++11 std (test for errors, line 3)
FAIL: g++.dg/cpp0x/auto27.C -std=c++11 auto (test for errors, line 3)
FAIL: g++.dg/cpp0x/auto27.C -std=c++11 no type (test for errors, line 3)
PASS: g++.dg/cpp0x/auto27.C -std=c++11 (test for excess errors)




-Message d'origine-
De : Joseph Myers [mailto:jos...@codesourcery.com] 
Envoyé : mardi 10 décembre 2013 18:22
À : BELBACHIR Selim
Cc : gcc@gcc.gnu.org
Objet : Re: cpp0x test suite PASS/FAIL

On Tue, 10 Dec 2013, BELBACHIR Selim wrote:

> FAIL: g++.dg/cpp0x/auto27.C -std=c++11 std (test for errors, line 3)
> FAIL: g++.dg/cpp0x/auto27.C -std=c++11 auto (test for errors, line 3)
> FAIL: g++.dg/cpp0x/auto27.C -std=c++11 no type (test for errors, line 
> 3)

That means that the desired result is an error message on that line, and either 
there was no such error message or the error message did not match what the 
testcase expected.

> Should I ignore the FAILs when the comment contains '(test for errors' 
> and consider that those tests are parts of a larger test with comment 
> '(test for excess errors' ?

No, FAILs indicate a bug in either the compiler or the testcase (or in your 
test environment, etc.); don't ignore them.

--
Joseph S. Myers
jos...@codesourcery.com


cpp0x test suite PASS/FAIL

2013-12-10 Thread BELBACHIR Selim
Hi,

I'm playing c++ testsuite on my gcc.4.7.3 port and I encounter the following 
result on test auto27.C

PASS: g++.dg/cpp0x/auto27.C -std=c++98 std (test for errors, line 3)
PASS: g++.dg/cpp0x/auto27.C -std=c++98 auto (test for errors, line 3)
PASS: g++.dg/cpp0x/auto27.C -std=c++98 no type (test for errors, line 3)
PASS: g++.dg/cpp0x/auto27.C -std=c++98 (test for excess errors)
FAIL: g++.dg/cpp0x/auto27.C -std=c++11 std (test for errors, line 3)
FAIL: g++.dg/cpp0x/auto27.C -std=c++11 auto (test for errors, line 3)
FAIL: g++.dg/cpp0x/auto27.C -std=c++11 no type (test for errors, line 3)
PASS: g++.dg/cpp0x/auto27.C -std=c++11 (test for excess errors)



auto27.C :

auto main()->int   // { dg-error "std=" "std" { target c++98 } }
   // { dg-error "auto" "auto" { target c++98 } 3 }
   // { dg-error "no type" "no type" { target c++98 
} 3 }
{ }



I don't understand if DejaGNU tells me that the test is OK or KO ...

When I use -std=c++98 option, I get the 3 expected errors and when I use 
-std=c++11, I get no error. That seems to be the expected result but I don't 
understand why the word FAIL appears in the log...

Should I ignore the FAILs when the comment contains '(test for errors' and 
consider that those tests are parts of a larger test with comment '(test for 
excess errors'  ?

   Regards,

Selim


RE: Controling reloads of movsicc pattern

2013-12-06 Thread BELBACHIR Selim
Any gnat official release ? Maybe gnat 7.2 beta is based on 4.8, I'll try to 
get this one.


-Message d'origine-
De : Andrew Pinski [mailto:pins...@gmail.com] 
Envoyé : vendredi 6 décembre 2013 09:54
À : BELBACHIR Selim
Cc : Jeff Law; gcc@gcc.gnu.org
Objet : Re: Controling reloads of movsicc pattern

On Fri, Dec 6, 2013 at 12:41 AM, BELBACHIR Selim 
 wrote:
> Hum, I can't change gcc branch because I'm tighted to gnat 7.1.2 based on gcc 
> 4.7.3 (I saw that LRA was merged in 4.8). I will use a workaround for the 
> moment (i.e. disable wide offset MEM on conditional moves).
> Does someone know if gnat frontend will rebase on 4.8 soon :) ? (or 
> maybe LRA will be merged in 4.7.4 ?)

If this is the Ada front-end, then it is already part of 4.8 release.
Or is this some other front-end?

Thanks,
Andrew Pinski


>
> Thanks
>
> Selim
>
> -Message d'origine-
> De : Jeff Law [mailto:l...@redhat.com]
> Envoyé : mercredi 4 décembre 2013 18:02 À : BELBACHIR Selim; 
> gcc@gcc.gnu.org Objet : Re: Controling reloads of movsicc pattern
>
> On 12/04/13 03:22, BELBACHIR Selim wrote:
>> Hi,
>>
>> My target has :
>> - 2 registers class to store SImode (like m68k, data $D & address $A).
>> - moves from wide offset MEM to $D or $A   (ex: mov d($A1+50),$A2   or
>> mov d($A1+50),$D1)
>> - conditional moves from offset MEM to $D or $A but with a restriction :
>>   offset MEM conditionally moved to $A has a limited offset 
>> of
>> 0 or 1 (ex: mov.ifEQ d($A1,1),$A1 whereas we can still do mov.ifEQ
>> d($A1,50),$D1)
>>
>> The predicate of movsicc pattern tells GCC that wide offset MEM is allowed 
>> and constraints describe 2 alternatives for 'wide offset MEM -> $D ' and 
>> 'restricted offset MEM -> $A" :
>>
>> (define_insn_and_split "movsicc_internal"
>>[(set (match_operand:SI 0 "register_operand" "=a,d,m,a,d,m,a,d,m")
>>  (if_then_else:SI
>>(match_operator 1 "prism_comparison_operator"
>> [(match_operand 4 "cc_register" "") (const_int 0)])
>>(match_operand:SI 2 "nonimmediate_operand"   " 
>> v,m,r,0,0,0,v,m,r") ;; "v" constraint is for restricted offset MEM
>>(match_operand:SI 3 " nonimmediate_operand" "
>> 0,0,0,v,m,r,v,m,r")))] ;; the last 3 alternatives are split to match 
>> the other alternatives
>>
>>
>>
>> I encountered : (on gcc4.7.3)
>>
>> core_main.c:354:1: error: insn does not satisfy its constraints:
>> (insn 1176 1175 337 26 (set (reg:SI 5 $A5)
>>  (if_then_else:SI (ne (reg:CC 56 $CCI)
>>  (const_int 0 [0]))
>>  (mem/c:SI (plus:SI (reg/f:SI 0 $A0)
>>  (const_int 2104 [0x838])) [9 %sfp+2104 S4 A32])
>>  (const_int 1 [0x1]))) core_main.c:211:32 158 
>> {movsicc_internal}
>>
>> Due to reload pass (core_main.c.199r.reload).
>>
>>
>> How can I tune reload or write my movsicc pattern to prevent reload pass 
>> from generating a conditional move from wide offset MEM to $A registers ??
> If at all possible, I would recommend switching to LRA.  There's an up-front 
> cost, but it's definitely the direction all ports should be heading.  
> Avoiding reload is, umm, good.
>
> jeff
>


RE: Controling reloads of movsicc pattern

2013-12-06 Thread BELBACHIR Selim
Hum, I can't change gcc branch because I'm tighted to gnat 7.1.2 based on gcc 
4.7.3 (I saw that LRA was merged in 4.8). I will use a workaround for the 
moment (i.e. disable wide offset MEM on conditional moves).
Does someone know if gnat frontend will rebase on 4.8 soon :) ? (or maybe LRA 
will be merged in 4.7.4 ?)

Thanks

Selim

-Message d'origine-
De : Jeff Law [mailto:l...@redhat.com] 
Envoyé : mercredi 4 décembre 2013 18:02
À : BELBACHIR Selim; gcc@gcc.gnu.org
Objet : Re: Controling reloads of movsicc pattern

On 12/04/13 03:22, BELBACHIR Selim wrote:
> Hi,
>
> My target has :
> - 2 registers class to store SImode (like m68k, data $D & address $A).
> - moves from wide offset MEM to $D or $A   (ex: mov d($A1+50),$A2   ormov 
> d($A1+50),$D1)
> - conditional moves from offset MEM to $D or $A but with a restriction :
>   offset MEM conditionally moved to $A has a limited offset of 
> 0 or 1 (ex: mov.ifEQ d($A1,1),$A1 whereas we can still do mov.ifEQ 
> d($A1,50),$D1)
>
> The predicate of movsicc pattern tells GCC that wide offset MEM is allowed 
> and constraints describe 2 alternatives for 'wide offset MEM -> $D ' and 
> 'restricted offset MEM -> $A" :
>
> (define_insn_and_split "movsicc_internal"
>[(set (match_operand:SI 0 "register_operand" "=a,d,m,a,d,m,a,d,m")
>  (if_then_else:SI
>(match_operator 1 "prism_comparison_operator"
> [(match_operand 4 "cc_register" "") (const_int 0)])
>(match_operand:SI 2 "nonimmediate_operand"   " v,m,r,0,0,0,v,m,r") 
> ;; "v" constraint is for restricted offset MEM
>(match_operand:SI 3 " nonimmediate_operand" " 
> 0,0,0,v,m,r,v,m,r")))] ;; the last 3 alternatives are split to match 
> the other alternatives
>
>
>
> I encountered : (on gcc4.7.3)
>
> core_main.c:354:1: error: insn does not satisfy its constraints:
> (insn 1176 1175 337 26 (set (reg:SI 5 $A5)
>  (if_then_else:SI (ne (reg:CC 56 $CCI)
>  (const_int 0 [0]))
>  (mem/c:SI (plus:SI (reg/f:SI 0 $A0)
>  (const_int 2104 [0x838])) [9 %sfp+2104 S4 A32])
>  (const_int 1 [0x1]))) core_main.c:211:32 158 
> {movsicc_internal}
>
> Due to reload pass (core_main.c.199r.reload).
>
>
> How can I tune reload or write my movsicc pattern to prevent reload pass from 
> generating a conditional move from wide offset MEM to $A registers ??
If at all possible, I would recommend switching to LRA.  There's an up-front 
cost, but it's definitely the direction all ports should be heading.  Avoiding 
reload is, umm, good.

jeff



Controling reloads of movsicc pattern

2013-12-04 Thread BELBACHIR Selim
Hi,

My target has : 
- 2 registers class to store SImode (like m68k, data $D & address $A).
- moves from wide offset MEM to $D or $A   (ex: mov d($A1+50),$A2   ormov 
d($A1+50),$D1)
- conditional moves from offset MEM to $D or $A but with a restriction : 
 offset MEM conditionally moved to $A has a limited offset of 0 or 1 
(ex: mov.ifEQ d($A1,1),$A1 whereas we can still do mov.ifEQ d($A1,50),$D1)

The predicate of movsicc pattern tells GCC that wide offset MEM is allowed and 
constraints describe 2 alternatives for 'wide offset MEM -> $D ' and 
'restricted offset MEM -> $A" :

(define_insn_and_split "movsicc_internal" 
  [(set (match_operand:SI 0 "register_operand" "=a,d,m,a,d,m,a,d,m")
(if_then_else:SI
  (match_operator 1 "prism_comparison_operator"
   [(match_operand 4 "cc_register" "") (const_int 0)])
  (match_operand:SI 2 "nonimmediate_operand"   " v,m,r,0,0,0,v,m,r")
 ;; "v" constraint is for restricted offset MEM
  (match_operand:SI 3 " nonimmediate_operand" " 0,0,0,v,m,r,v,m,r")))] 
;; the last 3 alternatives are split to match the other alternatives



I encountered : (on gcc4.7.3)
 
core_main.c:354:1: error: insn does not satisfy its constraints:
(insn 1176 1175 337 26 (set (reg:SI 5 $A5)
(if_then_else:SI (ne (reg:CC 56 $CCI)
(const_int 0 [0]))
(mem/c:SI (plus:SI (reg/f:SI 0 $A0)
(const_int 2104 [0x838])) [9 %sfp+2104 S4 A32])
(const_int 1 [0x1]))) core_main.c:211:32 158 {movsicc_internal}

Due to reload pass (core_main.c.199r.reload).


How can I tune reload or write my movsicc pattern to prevent reload pass from 
generating a conditional move from wide offset MEM to $A registers ??

   Regards,


Selim


RE: dwarf2out & var-tracking & cond_exec call

2013-11-29 Thread BELBACHIR Selim
I found my problem totally elsewhere (sorry to bother)

I was loosing proper NOTES during a COND_EXEC((..)(CALL(..))) split ...

   Selim

-Message d'origine-
De : gcc-ow...@gcc.gnu.org [mailto:gcc-ow...@gcc.gnu.org] De la part de 
BELBACHIR Selim
Envoyé : vendredi 29 novembre 2013 14:29
À : gcc@gcc.gnu.org
Objet : dwarf2out & var-tracking & cond_exec call

Hi,

I'm still porting my private backing from gcc 4.5.2 to  gcc 4.7.3.
When compiling the following code with -g option, I encountered "internal 
compiler error: in dwarf2out_var_location, at dwarf2out.c:20883"

void toto(int* , float);
void foo(int a, float b, int * c) {
  if (b)
toto(c, b);
}

I don't know well what should contain NOTES but when I look at the gcc_assert 
at dwarf2out.c:20883 :

  gcc_assert (prev
  && (CALL_P (prev)
  || (NONJUMP_INSN_P (prev)
  && GET_CODE (PATTERN (prev)) == SEQUENCE
  && CALL_P (XVECEXP (PATTERN (prev), 0, 0);

I would say that COND_EXEC(CALL(..)) handling is missing. Is It right or 
something went wrong on previous pass (var-tracking pass for example ...)

Here is my conditional call pattern :

(define_insn "call_cond"
  [(cond_exec (match_operator 3 "comparison_operator"
  [(match_operand 4 "cc_register" "") (const_int 0)])
  (parallel[
   (call (mem:SI (match_operand:SI 0 "call_address_op" " i,r"))
 (match_operand:SI 1 "immediate_operand"   " X,X"))
   (clobber (match_operand:SI 2 "register_operand" "=r,r"))]))]

Regards,

   Selim





dwarf2out & var-tracking & cond_exec call

2013-11-29 Thread BELBACHIR Selim
Hi,

I'm still porting my private backing from gcc 4.5.2 to  gcc 4.7.3.
When compiling the following code with -g option, I encountered "internal 
compiler error: in dwarf2out_var_location, at dwarf2out.c:20883"

void toto(int* , float);
void foo(int a, float b, int * c) {
  if (b)
toto(c, b);
}

I don't know well what should contain NOTES but when I look at the gcc_assert 
at dwarf2out.c:20883 :

  gcc_assert (prev
  && (CALL_P (prev)
  || (NONJUMP_INSN_P (prev)
  && GET_CODE (PATTERN (prev)) == SEQUENCE
  && CALL_P (XVECEXP (PATTERN (prev), 0, 0);

I would say that COND_EXEC(CALL(..)) handling is missing. Is It right or 
something went wrong on previous pass (var-tracking pass for example ...)

Here is my conditional call pattern :

(define_insn "call_cond"
  [(cond_exec (match_operator 3 "comparison_operator"
  [(match_operand 4 "cc_register" "") (const_int 0)])
  (parallel[
   (call (mem:SI (match_operand:SI 0 "call_address_op" " i,r"))
 (match_operand:SI 1 "immediate_operand"   " X,X"))
   (clobber (match_operand:SI 2 "register_operand" "=r,r"))]))]

Regards,

   Selim





RE: post_inc mem in parallel rtx

2013-11-22 Thread BELBACHIR Selim
Ok so I should avoid the auto_inc alternatives in PARALLEL. It's certainly a 
quite rare RTL and I doubt the effort worth it.


-Message d'origine-
De : Jeff Law [mailto:l...@redhat.com] 
Envoyé : vendredi 22 novembre 2013 17:55
À : BELBACHIR Selim; gcc@gcc.gnu.org
Objet : Re: post_inc mem in parallel rtx

On 11/22/13 09:43, BELBACHIR Selim wrote:
> Hi,
>
> I encountered a bug in cselib.c:2360 using gnat7.1.2 (gcc4.7.3)
>
>  /* The register should have been invalidated.  */
>gcc_assert (REG_VALUES (dreg)->elt == 0);<<== 
> assert(false)
>
>
> I investigated the dump and found that the crash occurred during 207r.dse2 
> pass.
>
> Here is what I saw in the previous dump (206r.pro_and_epilogue) :
>
> (insn 104 47 105 7 (parallel [
>  (set (reg:CC_NOOV 56 $CCI)
>  (compare:CC_NOOV (minus:SI (reg/f:SI 22 $R6 [orig:133 D.3274 
> ] [133])
>  (mem/f:SI (post_inc:SI (reg:SI 2 $R2 [orig:140 
> ivtmp.363 ] [140])) [0 MEM[base: D.4517_59, offset: 0B]+0 S4 A32]))
>  (const_int 0 [0])))
>  (set (reg:SI 16 $R0 [153])
>  (minus:SI (reg/f:SI 22 $R6 [orig:133 D.3274 ] [133])
>  (mem/f:SI (post_inc:SI (reg:SI 2 $R2 [orig:140 ivtmp.363 
> ] [140])) [0 MEM[base: D.4517_59, offset: 0B]+0 S4 A32])))
>  ])
>
> Note the post_inc MEM on $R2 appearing twice
>
> This rtl match my pattern (predicate and contraint ok) below :
>
> (define_insn "subsi3_compare0"
>[(set (reg:CC_NOOV CCI_REG)
>  (compare:CC_NOOV
>(minus:SI
>  (match_operand:SI 1 "general_operand" "g")
>  (match_operand:SI 2 " general_operand " " g"))
>(const_int 0)))
> (set (match_operand:SI 0 "register_operand" "=r ")
>  (minus:SI
>(match_dup 1)
>(match_dup 2)))]
>
> But I think It may be an error to authorize post_inc MEM in this parallel rtx 
> in operand 1 & 2.
> When I put a more restrictive constraint which forbid the use of post_inc, 
> the crash in cselib.c disappear.
>
> Question : What does GCC understand when the md describes a pattern allowing 
> the same post_inc MEM in 2 slot of a parallel rtx ?
> Is it forbidden ? the MEM address is supposed to be incremented twice ?
I think the semantics are defined by the PARALLEL.  Namely that the uses are 
evaluated, then side effects are performed.  So both sets use the value before 
incrementing.

The only question is what is the resulting value, and given the fundamental 
nature of PARALLEL, I think a single visible side effect is the most obvious 
answer.

Now having said that, there's a distinct possibility various passes don't 
handle this properly.

jeff


RE: cross compile & exceptions

2013-11-22 Thread BELBACHIR Selim
>> 
>> So, to build libgcc I would need --without-header to compensate for my small 
>> libc, and to build libstdc++ I would have to use --with-header in order to 
>> provide stdio.h ...
>> 
>> 
>> Do you know a better way to solve that than building gcc, libgcc & libstdc++ 
>> independently ?

> What is $(TARGET) ?

>Andrew.

$(TARGET) is a private embedded platform (cpu/os/lib)

Selim



post_inc mem in parallel rtx

2013-11-22 Thread BELBACHIR Selim
Hi,

I encountered a bug in cselib.c:2360 using gnat7.1.2 (gcc4.7.3) 

/* The register should have been invalidated.  */
  gcc_assert (REG_VALUES (dreg)->elt == 0);<<== 
assert(false)


I investigated the dump and found that the crash occurred during 207r.dse2 pass.

Here is what I saw in the previous dump (206r.pro_and_epilogue) :

(insn 104 47 105 7 (parallel [
(set (reg:CC_NOOV 56 $CCI)
(compare:CC_NOOV (minus:SI (reg/f:SI 22 $R6 [orig:133 D.3274 ] 
[133])
(mem/f:SI (post_inc:SI (reg:SI 2 $R2 [orig:140 
ivtmp.363 ] [140])) [0 MEM[base: D.4517_59, offset: 0B]+0 S4 A32]))
(const_int 0 [0])))
(set (reg:SI 16 $R0 [153])
(minus:SI (reg/f:SI 22 $R6 [orig:133 D.3274 ] [133])
(mem/f:SI (post_inc:SI (reg:SI 2 $R2 [orig:140 ivtmp.363 ] 
[140])) [0 MEM[base: D.4517_59, offset: 0B]+0 S4 A32])))
])

Note the post_inc MEM on $R2 appearing twice

This rtl match my pattern (predicate and contraint ok) below :

(define_insn "subsi3_compare0"
  [(set (reg:CC_NOOV CCI_REG)
(compare:CC_NOOV
  (minus:SI 
(match_operand:SI 1 "general_operand" "g")
(match_operand:SI 2 " general_operand " " g"))
  (const_int 0)))
   (set (match_operand:SI 0 "register_operand" "=r ")
(minus:SI
  (match_dup 1)
  (match_dup 2)))]

But I think It may be an error to authorize post_inc MEM in this parallel rtx 
in operand 1 & 2. 
When I put a more restrictive constraint which forbid the use of post_inc, the 
crash in cselib.c disappear.

Question : What does GCC understand when the md describes a pattern allowing 
the same post_inc MEM in 2 slot of a parallel rtx ?
Is it forbidden ? the MEM address is supposed to be incremented twice ?

Regards,

Selim



RE: cross compile & exceptions

2013-11-22 Thread BELBACHIR Selim
I did this in order to build gcc, libgcc and libstdc++ independently.


when I do the simple integrated build process (following 
http://gcc.gnu.org/install)  :

cd $(GCC_OBJDIR); CFLAGS="-g -O0" $(GCC_SRCDIR)/configure 
-quiet 
--prefix=$(INSTALLDIR) 
--target=$(TARGET) 
--enable-languages=c,c++,ada 
--disable-nls 
--disable-decimal-float 
--disable-fixed-point 
--disable-libmudflap 
--disable-libffi 
--disable-libssp 
--disable-shared 
--disable-threads 
--without-headers
--disable-libada 
--enable-version-specific-runtime-lib 
--disable-bootstrap
--enable-checking=release
make -C $(GCC_OBJDIR)



I encounter a problem on libstdc++v3 :

Configuring in prism/libstdc++-v3
Configuring in prism/libiberty
configure: error: Link tests are not allowed after GCC_NO_EXECUTABLES.
make[2]: *** [configure-target-libiberty] Error 1
make[2]: *** Waiting for unfinished jobs
configure: error: Link tests are not allowed after GCC_NO_EXECUTABLES.
make[2]: *** [configure-target-libstdc++-v3] Error 1
make[1]: *** [all] Error 2
make: *** [gcc_make] Error 2

because stdio.h is not found  (my libc is externally built and --without-header 
prevent gcc from knowing where are these headers)



I tried --with-headers with my own libc header files (incomplete home made 
libc)  but this time I found stuck on libgcc2 requiring unistd.h that I don't 
have (or want) :

In file included from 
/vues_statiques/FPGA/belbachir/prism2/MPUCores/tools/gcc-4.5.2/libgcc/../gcc/libgcc2.c:29:0:
/vues_statiques/FPGA/belbachir/prism2/MPUCores/tools/gcc-4.5.2/libgcc/../gcc/tsystem.h:102:20:
 fatal error: unistd.h: No such file or directory
compilation terminated.



So, to build libgcc I would need --without-header to compensate for my small 
libc, and to build libstdc++ I would have to use --with-header in order to 
provide stdio.h ...


Do you know a better way to solve that than building gcc, libgcc & libstdc++ 
independently ?




RE: how to use -fomit-frame-pointer by default

2013-11-20 Thread BELBACHIR Selim
Thx that's what I was looking for :) I forgot the new gcc/common/config part ...


-Message d'origine-
De : Joseph Myers [mailto:jos...@codesourcery.com] 
Envoyé : mercredi 20 novembre 2013 17:41
À : BELBACHIR Selim
Cc : gcc@gcc.gnu.org
Objet : Re: how to use -fomit-frame-pointer by default

On Tue, 19 Nov 2013, BELBACHIR Selim wrote:

> I'm migrating my private port from gcc 4.5.2 to gcc 4.7.3. I noticed 
> that -fomit-frame-pointer was not triggered when using -O1 -O2 or -O3.
> Could you indicate me how to modify my port to use 
> -fomit-frame-pointer by default (as it was in gcc 4.5.2 I presume) ?

This is now handled through the TARGET_OPTION_OPTIMIZATION_TABLE hook (in 
gcc/common/config).

--
Joseph S. Myers
jos...@codesourcery.com


cross compile & exceptions

2013-11-20 Thread BELBACHIR Selim
Hi,

I'm trying to migrate from gcc4.5.2 to gcc4.7.3. 

Here are a part of my makefile to build gcc (same config used with gcc4.5.2 and 
gcc4.7.3) :

cd $(GCC_OBJDIR); CFLAGS="-g -O0" $(GCC_SRCDIR)/configure 
-quiet 
--prefix=$(INSTALLDIR) 
--target=$(TARGET) 
--enable-languages=c,c++,ada 
--disable-nls 
--disable-decimal-float 
--disable-fixed-point 
--disable-libmudflap 
--disable-libffi 
--disable-libssp 
--disable-shared 
--disable-threads 
--without-headers
--disable-libada 
--enable-version-specific-runtime-lib 
--enable-checking=release

make -C $(GCC_OBJDIR) all-gcc

make -C $(GCC_OBJDIR) install-gcc



The c++ (and not c) compiler produced segmentation fault on very small source 
only when I use default option -O0

cmd : pgcc test.cpp -S

src :
extern void bar(int *);
void toto () {
  int tmp;
  bar (&tmp);
}

Looking at the dumps I noticed in test.cpp.152r.rtl_eh that a bad RTL SET is 
generated inside a bunch of rtl dealing with exception.

(insn 19 20 12 5 (set (reg:SI 131)
(reg:SI -1)) -1<<<--- REG -1 is 
invalid
 (nil))

(insn 12 19 13 5 (set (reg/f:SI 130 [ D.1841 ])
(reg:SI 131)) -1
 (nil))

(insn 13 12 14 5 (set (reg:SI 4 $C4)
(reg/f:SI 130 [ D.1841 ])) -1
 (nil))

(call_insn 14 13 15 5 (parallel [
(call (mem:SI (symbol_ref:SI ("_Unwind_Resume") [flags 0x41]  
) [0 
__builtin_unwind_resume S4 A32])
(const_int 0 [0]))
(clobber (reg:SI 1 $C1))
]) -1


I don't want need/want exceptions on my port and it seems that -00 always 
produce some extra code to handle exception in c++. That was not the normal 
behaviour of gcc4.5.2. 

I don't see any good configure option but I tried --enable-sjlj-exceptions to 
see the result. The segmentation fault disappears but extra code to call 
_Unwind_SjLj_Register is produced (with a save of all registers in function 
prologue ...), that's not what I wanted.  Configure using 
--disable-sjlj-exceptions produce the same segmentation described above.

I also tried to compile my test with -fno-exceptions. It produces the result I 
expected with no error and no extra code equivalent to the gcc4.5.2 without 
options.

Something new in gcc4.7.3 has to be configured to disable exceptions by default 
?


I noticed a change of behaviour on -fomit-frame-pointer between 4.5.2 & 4.7.3 
(described in my previous post). gcc4.5.2 behaviour was exactly what I wanted 
(fomit-frame-pointer & fno-exceptions by default) how to obtain that with 4.7.3 
 ?

Regards,

Selim




how to use -fomit-frame-pointer by default

2013-11-19 Thread BELBACHIR Selim
Hi,

I'm migrating my private port from gcc 4.5.2 to gcc 4.7.3. I noticed that 
-fomit-frame-pointer was not triggered when using -O1 -O2 or -O3.
Could you indicate me how to modify my port to use -fomit-frame-pointer by 
default (as it was in gcc 4.5.2 I presume) ?

Regards,

Selim


RE: delay slot of conditionnal branch with no annuled jump strategy

2013-10-14 Thread BELBACHIR Selim
Thanks for the hints ! 
I found a recent correction on resource.c ' 
https://github.com/mirrors/gcc/commit/d8e17376c1b6ba379cc918f06843792e35c4e38e' 
which treat my problem.
It seems my problem was not related to my parallel compare insn but produced by 
the conditional call at the beginning of the target path.
Let's hope this correction does not hide another problem by just applying a 
side effect on my specific test case :)
  
   Regards,

Selim

-Message d'origine-
De : Jeff Law [mailto:l...@redhat.com] 
Envoyé : vendredi 11 octobre 2013 22:34
À : BELBACHIR Selim; Eric Botcazou
Cc : gcc@gcc.gnu.org
Objet : Re: delay slot of conditionnal branch with no annuled jump strategy

On 10/11/13 05:51, BELBACHIR Selim wrote:
>
>> Does this happen systematically with the compare insn or is it isolated?
>
> I encountered this problem only once in gcc testsuite 
> (gcc.c-torture/execute/builtins/strncat-chk.c).
> I think the problem is quite rare because gcc does not put often a 
> parallel compare insn into the delay slot of a conditional jump, and when it 
> happens it's not certain that the register clobbered by the parallel compare 
> is used in the fall-through path after the conditional jump.
> So I would say the problem is isolated.
>
>> This looks like a bug in the dbr pass (several of them have been 
>> fixed since
>> 4.5.2) but it's impossible to be more precise without further details.  The 
>> support of annulled instructions is not required for proper operation.
>
> My current investigation showed that when I comment the call to 
> 'fill_eager_delay_slots' in ' reorg.c:dbr_schedule' the problem disappear.
> The problem does not come from the 2 others techniques for filling delay 
> slots : 'fill_simple_delay_slots' or 'relax_delay_slots'.
>
> To illustrate the problem previously described in asm, I copied and commented 
> the rtl dumps below :
I'd look at the code in resource.c very carefully, it's possible it's not 
properly handling all the side effects of the parallel.

jeff



RE: delay slot of conditionnal branch with no annuled jump strategy

2013-10-11 Thread BELBACHIR Selim

> I have a gcc 4.6.1 port that has the same sort of  problems.  I tried 
> selectively porting some patches from later 4.6 releases, but they didn't 
> seem to actually address the issue.  I haven't looked at the trunk to see if 
> there are patches that are more apropos.

I looked at the revisions of reorg.c in gitHub since gcc 4.5.2 but I did not 
see any obvious correction concerning this issue. 



RE: delay slot of conditionnal branch with no annuled jump strategy

2013-10-11 Thread BELBACHIR Selim

> Does this happen systematically with the compare insn or is it isolated?

I encountered this problem only once in gcc testsuite 
(gcc.c-torture/execute/builtins/strncat-chk.c).
I think the problem is quite rare because gcc does not put often a parallel 
compare insn into the delay slot of a conditional jump, 
and when it happens it's not certain that the register clobbered by the 
parallel compare is used in the fall-through path after the conditional jump.
So I would say the problem is isolated.

> This looks like a bug in the dbr pass (several of them have been fixed since
> 4.5.2) but it's impossible to be more precise without further details.  The 
> support of annulled instructions is not required for proper operation.

My current investigation showed that when I comment the call to 
'fill_eager_delay_slots' in ' reorg.c:dbr_schedule' the problem disappear. 
The problem does not come from the 2 others techniques for filling delay slots 
: 'fill_simple_delay_slots' or 'relax_delay_slots'.

To illustrate the problem previously described in asm, I copied and commented 
the rtl dumps below :

--
* Dumps before dbr scheduling (dump xx.214r.barriers) 
--

### compare $R5 to 0 ($R1 is clobbered)
(insn 38 97 39 test.c:14:21 (parallel [
(set:CC (reg:CC 56 $CCI)
(compare:CC (reg:SI 18 $R5 [108])
(const_int 0 [0x0])))
(clobber (reg:SI 18 $R1 [109]))
]) 45 {compare} (expr_list:REG_DEAD (reg:SI 18 $R5 [108])
(nil)))

### conditionnal branch to label 51
(jump_insn 39 38 71 test.c:14:21 (set (pc)
(if_then_else (eq (reg:CC 56 $CCI)
(const_int 0 [0x0]))
(label_ref 51)
(pc))) 131 {jmpif} (expr_list:REG_DEAD (reg:CC 56 $CCI)
(expr_list:REG_BR_PROB (const_int 900 [0x384])
(nil)))
 -> 51)

(code_label 71 39 70 6 "" [1 uses])

(note 70 71 41 [bb 3] NOTE_INSN_BASIC_BLOCK)

### increment $R0 in fall-through path
(insn 41 70 43 test.c:16:7 (set (reg/v:SI 16 $R0 [orig:85 len ] [85])
(plus:SI (reg/v:SI 16 $R0 [orig:85 len ] [85])
(const_int 1 [0x1]))) 40 {addsi3_nocompare} (nil))

### I have hidden some insn not very usefull
[...]

### target of the conditionnal jump
(code_label 51 50 52 3 "" [1 uses])

(note 52 51 53 [bb 4] NOTE_INSN_BASIC_BLOCK)

### compare $R4 to $R0 ($R0 is clobbered)
(insn 53 52 56 test.c:19:11 (parallel [
(set:CC (reg:CC 56 $CCI)
(compare:CC (reg/v:SI 20 $R4 [orig:93 size ] [93])
(reg/v:SI 16 $R0 [orig:85 len ] [85])))
(clobber (reg:SI 16 $R0 [117]))
]) 45 {compare} (expr_list:REG_DEAD (reg/v:SI 20 $R4 [orig:93 size ] 
[93])
(expr_list:REG_DEAD (reg/v:SI 16 $R0 [orig:85 len ] [85])
(nil

(note 56 53 57 NOTE_INSN_DELETED)

### conditionnal call symbol_ref
(call_insn 57 56 60 test.c:20:16 (cond_exec (leu (reg:CC 56 $CCI)
(const_int 0 [0x0]))
(parallel [
(set (reg:SI 16 $R0)
(call (mem:SI (symbol_ref:SI ("__chk_fail") [flags 0x41]  
) [0 S4 A32])
(const_int 0 [0x0])))
(clobber (reg:SI 1 $C1))
])) 161 {call_value_cond} (expr_list:REG_DEAD (reg:SI 1 $C1)



--
* Dumps after dbr scheduling (dump xx.c.215r.db)
--

### compare $R5 to 0 ($R1 is clobbered)
(insn 38 97 121 test.c:14:21 (parallel [
(set:CC (reg:CC 56 $CCI)
(compare:CC (reg:SI 18 $R5 [108])
(const_int 0 [0x0])))
(clobber (reg:SI 18 $R1 [109]))
]) 45 {compare} (expr_list:REG_DEAD (reg:SI 18 $R5 [108])
(nil)))

### conditionnal branch to label 51 with delay slot filled by parallel [compare 
$R4 to $R0, clobber $R0].
### the parallel compare was taken from the conditional jump 'target' path and 
should not have any side effect
### on the 'fall-through' path. But unfortunately the clobber $R0 has side 
effect ...
(insn 121 38 70 test.c:14:21 (sequence [
(jump_insn 39 38 119 test.c:14:21 (set (pc)
(if_then_else (eq (reg:CC 56 $CCI)
(const_int 0 [0x0]))
(label_ref:SI 120)
(pc))) 131 {jmpif} (expr_list:REG_BR_PRED (const_int 48 
[0x30])
(expr_list:REG_DEAD (reg:CC 56 $CCI)
(expr_list:REG_BR_PROB (const_int 900 [0x384])
(nil
 -> 120)
(insn/s 119 39 70 (parallel [
(set:CC (reg:CC 56 $CCI)
(compare:CC (reg/v:SI 20 $R4 [orig:93 size ] [93])
(reg/v:SI 16 $R0 

delay slot of conditionnal branch with no annuled jump strategy

2013-10-10 Thread BELBACHIR Selim
Hi,

I'm porting gcc 4.5.2 on a private processor.
I encountered a problem concerning delay slots of conditionnal branch 
instructions (Note : the processor has no 'annuled jump strategy')


Here is my delay slot definition :

 (define_delay (eq_attr "type" "jump")
   [(and (eq_attr "delayable" "yes") (eq_attr "length" "1")) (nil) (nil)])



Here is a sample of erroneous code :


sub 0,$R5,$R1   #compare $R5 to 0 ($R1 is clobbered)
jmpd.ifCC .L0#conditionnal delayed branch followed by 1 
delay slot
sub $R0,$R4,$R0  #compare $R4 to $R0 ($R0 is clobbered) 
    problem
   ...
addk 1,$R0,$R0#increment $R0,   but $R0 was modified by 'sub 
$R0,$R4,$R0' !!!
   ...
   .L0:
bra.ifLS __chk_fail#conditionnal call symbol_ref


GCC put my compare insn 'sub $R0,$R4,$R0' into the delay slot knowing that $R0 
was clobbered by the compare insn (see the definition below).
It's ok if 'jmpd.ifCC .L7' jumps otherwize it's ko because $R0 is used in the 
fall-through path by 'addk 1,$R0,$R0'.



Here is my compare insn :

 (define_insn "compare"
   [(set (reg:CC CCI_REG)
 (compare:CC
   (match_operand:SI 1 "general_operand""g ")
   (match_operand:SI 2 "general_operand""g")))
(clobber (match_operand:SI 0 "register_operand" "=r "))]
   "sub %2,%1,%0"
  [(set_attr "length" "1")
  (set_attr " delayable " "yes")]
 )


I was expecting 'instruction reorganization pass' to produce the following code 
:

sub 0,$R5,$R1   #compare $R5 to 0 ($R1 is clobbered)
jmp.ifCC .L0  #conditionnal delayed branch (with 0 delay 
slot)
...
addk 1,$R0,$R0#increment $R0
...
   .L0:
sub $R0,$R4,$R0   #compare $R4 to $R0 ($R0 is clobbered)
bra.ifLS __chk_fail#conditionnal call symbol_ref



Why GCC doesn't see, in this case, that it's not safe to fill the delay slot 
with my compare insn (which is a parallel RTX which clobber one register used 
in fallthrough branch) ?
Is a processor 'annuled jump strategy' mandatory to handle delay slot of 
conditionnal jump instructions ?


   Regards,


Selim Belbachir


DWARF2 offset for local variables

2013-05-03 Thread BELBACHIR Selim
Hi,

I'm (still) working on a new gcc-4.5.2 backend for a private processor.
Today i'm concerned about the debug mode using DWARF2.

Here is my problem:
When I use GDB on a executable compiled with -g option I notice that the 
addresses of all my local variables are wrong.
I read gccint doc and tried to use DEBUGGER_AUTO_OFFSET(X) and 
DEBUGGER_ARG_OFFSET(OFFSET, X) but I noticed (thanks to printf) that they were 
never called for DWARF2. (I saw afterward that dwarf2out.c did not use these 
macros)

My stack frame is organized as follow :

Hi mem Address |   |
   +---+ <= $SP before prologue
   |   |
   | Reg save  |
   |   |
   +---+
   |   |
   |  Locals / Temps   |
   |   |
   +---+
   |   |
   |Args Block |
   |   |
   +---+ <= $SP after prologue
Lo mem Address |   |
  

With 

#define STACK_GROWS_DOWNWARD 1
#define FRAME_POINTER_CFA_OFFSET(FNDECL) 0
#define STARTING_FRAME_OFFSET crtl->outgoing_args_size
#define FIRST_PARM_OFFSET(FUNDECL) 0
#define DWARF2_DEBUGGING_INFO
#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG  
#define ELIMINABLE_REGS \
  {{HARD_FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
   {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
   {FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \
   {ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
   {ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \
  }
#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
  (OFFSET) = my_initial_elimination_offset ((FROM), (TO))


HOST_WIDE_INT my_initial_elimination_offset (int from, int to ATTRIBUTE_UNUSED)
{
  HOST_WIDE_INT offset;
  switch (from)
  {
  case HARD_FRAME_POINTER_REGNUM:
offset = 0;
break;
  case FRAME_POINTER_REGNUM:
offset = 0;
break;
  case ARG_POINTER_REGNUM:
offset = my_stack_frame_size();
break;
  default:
gcc_unreachable ();
  }
  return offset;
}


How can I express an offset for local variables in DWARF2 for GDB ?


Regards,

Selim Belbachir



ADA runtime System.Address type

2013-02-01 Thread BELBACHIR Selim
Hi,

I'm working on a gcc/gnat port  for a private target (gcc 4.5.2, gnat 6.4.2).
On this target, scalar values shall be stored in $R registers whereas pointer 
values shall be stored in $C registers. My current ABI for procedure/function 
calls uses $R and $C registers depending on arguments and return values type 
(scalar or pointer). I need an ABI of this kind for performance reasons (the 
instruction set does not allow $R and $C everywhere and copying $R in $C for 
each procedure calls is too expensive).

I tested this ABI through GCC C and C++ torture suite and everything is ok 
(after solving special cases for implicit calls)

During my tests I tried to mix ADA and C sources code using the 'pragma 
import/export'. For example I tried to implement the "__gnat_malloc" expected 
by the ZFP runtime by an ADA function and 'pragma export' :

function Gnat_Malloc (Size : in Integer) return System.Address is
begin
-- implementation
end Gnat_Malloc;
pragma Export (C, Gnat_Malloc, "__gnat_malloc");

Here is my problem :
* the caller of __gnat_malloc expects that return value of type pointer to be 
in a $C register (as defined in the ABI)
* the called function Gnat_Malloc return a value of type system.address in $R 
register because system.address is considered as a scalar value (system.ads:   
type Address is mod Memory_Size;) 
==> caller and callee return values doesn't match, the ABI is broken

I tried to modified system.ads so that system.address arguments become pointers 
(using access keyword) but I can't figure out how to do this because the System 
package is 'pragma Pure' ...

Is there a way to modify something somewhere (runtime, backend, frontend ...) 
so that arguments of type system.address are seen as pointers and not scalar 
values ?

Regards,

  Selim Belbachir







RE: type argument in FUNCTION_ARG macro

2012-05-04 Thread BELBACHIR Selim
Ok thanks, I'll keep on with plan B (INIT_CUMULATIVE_LIBCALL_ARGS with special 
libcall handling)

Selim

-Message d'origine-
De : Ian Lance Taylor [mailto:i...@google.com] 
Envoyé : vendredi 4 mai 2012 15:58
À : BELBACHIR Selim
Cc : gcc@gcc.gnu.org
Objet : Re: type argument in FUNCTION_ARG macro

BELBACHIR Selim  writes:

> I'm working on an architecture where the calling convention depends on the 
> type of the parameter (i.e. pointers are passed into $C regs and non-pointers 
> are passed into $R regs).  I've implemented this difference by using the 
> POINTER_TYPE_P() macro on the 'type' argument of the FUNCTION_ARG macro.
>
> I'm having a problem with this approach with calls to libgcc function 
> like  _Unwind_SjLj_Register(struct foo * ). As this function is invoked as a 
> library function, the 'type' argument to the FUNCTION_ARG() macro is NULL.  
> Thus, the pointer parameter is not passed as pointer but the function body 
> expects a pointer.
>
> Any ideas on how to get around this problem?

If possible, avoid using SJLJ exceptions.  DWARF exceptions are better.

I see three ways to go.

Change the middle-end to avoid using emit_library_call when calling 
_Unwind_SjLj_Register.  There is no particular reason for making this a special 
library call.  But this is probably a bit painful to implement.

Define INIT_CUMULATIVE_LIBCALL_ARGS for your target, and check the function.  
If it's _Unwind_SjLj_Register, apply special handling.  This option is nice 
because you only have to change your backend.

Change the implementation of _Unwind_SjLj_Register to take a parameter of type 
uintptr_t, and cast it to struct SjLj_Function_Context *.

Ian


RE: type argument in FUNCTION_ARG macro

2012-05-04 Thread BELBACHIR Selim
That's the only option ? Is there a  more general method to do this ?


-Message d'origine-
De : amyl...@spamcop.net [mailto:amyl...@spamcop.net] 
Envoyé : vendredi 4 mai 2012 15:48
À : BELBACHIR Selim
Cc : gcc@gcc.gnu.org
Objet : Re: type argument in FUNCTION_ARG macro

Quoting BELBACHIR Selim :

> Any ideas on how to get around this problem?

You can look at the name of library functions.


type argument in FUNCTION_ARG macro

2012-05-04 Thread BELBACHIR Selim
Hi,

I'm working on an architecture where the calling convention depends on the type 
of the parameter (i.e. pointers are passed into $C regs and non-pointers are 
passed into $R regs).  I've implemented this difference by using the 
POINTER_TYPE_P() macro on the 'type' argument of the FUNCTION_ARG macro.

I'm having a problem with this approach with calls to libgcc function like  
_Unwind_SjLj_Register(struct foo * ). As this function is invoked as a 
library function, the 'type' argument to the FUNCTION_ARG() macro is NULL.  
Thus, the pointer parameter is not passed as pointer but the function body 
expects a pointer.  

Any ideas on how to get around this problem?

Regards,

   Selim


RE: readonly register

2012-01-19 Thread BELBACHIR Selim
In fact my final purpose is to replace $INP by a register bank in order to be 
able to read several inputs using pipelined instructions (and instruction 
scheduler). The fixed reg solution will prevent me from doing this. Is there 
another way to prevent the use of some registers during the reload pass without 
turning them into fixed register ?

Selim

-Message d'origine-
De : Ian Lance Taylor [mailto:i...@google.com] 
Envoyé : jeudi 19 janvier 2012 00:17
À : BELBACHIR Selim
Cc : gcc@gcc.gnu.org
Objet : Re: readonly register

BELBACHIR Selim  writes:

> I'm trying to support an 'in' instruction which reads a value on a peripheral 
> and writes it into a $INP register.
> The $INP register can be used in almost every insn as input operand (add, 
> sub, mul ...).
> I defined a builting to access the 'in' instruction.
>
> How should I express to gcc that the $INP register can only be 'read' and 
> must never be written?
>
> For the moment, I encounter a problem during IRA pass where some of my 
> 'classic' registers are reloaded into $INP (apparently because I have no 
> register left).

If you have a builtin to access the value, then you should be able to
make it a fixed register.  The register allocator will never try to
allocate a fixed register.

Ian


readonly register

2012-01-18 Thread BELBACHIR Selim
Hi,

I'm trying to support an 'in' instruction which reads a value on a peripheral 
and writes it into a $INP register.
The $INP register can be used in almost every insn as input operand (add, sub, 
mul ...).
I defined a builting to access the 'in' instruction.

How should I express to gcc that the $INP register can only be 'read' and must 
never be written?

For the moment, I encounter a problem during IRA pass where some of my 
'classic' registers are reloaded into $INP (apparently because I have no 
register left).

Regards,

  Selim




reverse conditionnal jump

2012-01-05 Thread BELBACHIR Selim
Hi,

I'm still developping a new private target backend (gcc4.5.2) and I noticed 
something strange in the assembler generated for conditionnal jump.


The compiled C code source is :

void funct (int c) {
int a;
a = 7;
if (c < 0)
  a = 4;
return a;
}


The assembler generated is :

[...]
  mov 7,a
  cmp 0,c  #set the CC status
  jmpif LT .L2 #conditionnal jump using CC status
.L1
  ret a #return to callee
.L2
  mov 4,a
  jmp .L1 #unconditionnal jump


But, I was expecting only one jump as follow :

[...]
  mov 7,a
  cmp 0,c #set the CC status
  jmpif GE .L1 #conditionnal jump using CC status
  mov 4,a
.L1
  ret a #return to callee


All comparison are available and I defined REVERSIBLE_CC_MODE(MODE) to 1.

I also have the following branch insn (and the cbranchsi4 expand)

(define_insn "*jmpif"
  [(set (pc) 
(if_then_else (match_operator 0 "comparison_operator"
  [(reg:CC CCI_REG) (const_int 0)])
(label_ref (match_operand 1 "" ""))
(pc)))]
""
"jmpif %c0 %l1"
)

(define_insn "*reverse_jmpif"
  [(set (pc) 
(if_then_else (match_operator 0 "comparison_operator"
  [(reg:CC CCI_REG) (const_int 0)])
(pc)
(label_ref (match_operand 1 "" ""]
""
"jmpif %C0 %l1"
)


How can I tell GCC to perform the best conditionnal jump by sometimes reversing 
the comparison ?

   Regards,

 Selim




RE: add and compare combination

2011-12-16 Thread BELBACHIR Selim
Well, I run combine pass in debug mode and found my mistakes. I'd like to share 
what I have found :)

There were 2 mistake. First my HARD_REGNO_MODE_OK returned 0 for regno=CCI_REG 
and mode=CCmode which lead to an early failure in combine.c.
So I added this to my macro :

if (GET_MODE_CLASS (mode) == MODE_CC)
  return (regno == CCI_REG)




Secondly, I figured out that combination was different for the 2 following code 
:

c = a + b;
if (c) {...} /* use c further in code */

and

if (a + b) {...} /* the addition result is a DEAD_REG */


In the first case the combiner create and try to match a parallel rtx similar 
to my "add_and_compare". This case was in fact working.
In the second case the combiner see the DEAD_REG and try to match a single set 
rtx of this form :

(define_insn "comparesi_plus"
  [(set (reg:CC CCI_REG)
(compare:CC
  (match_operand:SI 0 "register_operand" "r")
  (neg:SI (match_operand:SI 1 "register_operand" "r"]  ;; the 
'trick' is in the neg !!
  ""
  "cmp_plus %1,%0"
)

As I had no such insn the combination was failing, when I added one (with a 
clobbered result because I have no cmp_plus instruction), everything run ok. I 
watched in arm backend and I found a similar insn... So the solution was in 
front of me but I did not see it :)

Selim


-Message d'origine-
De : gcc-ow...@gcc.gnu.org [mailto:gcc-ow...@gcc.gnu.org] De la part de 
BELBACHIR Selim
Envoyé : jeudi 15 décembre 2011 16:12
À : gcc@gcc.gnu.org
Objet : add and compare combination

Hi,

I'd like to know if there a way to express 'add' and 'compare' insn so that the 
combiner transform it in and 'add_and_compare' insn.

I watch arm backend and it seems possible when I look at 'addsi3', 'cbranchsi4' 
and '*addsi3_compare0'.

In my backend I have written the following insn/expand :

(define_expand "addsi3"
  [(set (match_operand:SI  0 "register_operand" "")
(plus:SI (match_operand:SI 1 "general_operand" "")
(match_operand:SI 2 "off1post_general_op" "")))]
   ""
   ""
)

(define_insn "add_and_compare"
  [(set (reg:CC CCI_REG)
(compare:CC
  (plus:SI
(match_operand:SI 1 "register_operand" "%r")
(match_operand:SI 2 "register_operand" "r"))
  (const_int 0)))
   (set (match_operand:SI 0 "register_operand"  "=r")
  (plus:SI
(match_dup 1)
(match_dup 2)))]
   ""
   "add %1,%2,%0"
)

(define_insn "add"
  [(set (match_operand:SI 0 "register_operand"  "=r")
  (plus:SI
(match_operand:SI 1 "register_operand" "%r")
(match_operand:SI 2 "register_operand" "r")))]
   ""
   "addk %1,%2,%0"
)

(define_expand "cbranchsi4"
  [(set (pc) 
(if_then_else (match_operator 0 "comparison_operator"
   [(match_operand:SI 1 "register_operand" "")
(match_operand:SI 2 "register_operand" "")])
(label_ref (match_operand 3 "" ""))
(pc)))]
  
  {
emit_insn(gen_comparesi (operands[1], operands[2]));
  
operands[1] = gen_rtx_REG (CCmode, CCI_REG);
operands[2] = const0_rtx;
  }
)

(define_insn "comparesi"
  [(set (reg:CC CCI_REG)
(compare:CC
  (match_operand:SI 0 "register_operand" "r")
  (match_operand:SI 1 "register_operand" "r")))]
  ""
  "cmp %1,%0"
)

(define_insn "jmpifsi"
  [(set (pc) 
(if_then_else (match_operator 0 "comparison_operator"
  [(reg:CC CCI_REG) (const_int 0)])
(label_ref (match_operand 1 "" ""))
(pc)))]
  ""
  "jmp.if %c0 %1"
)

When I compile :

c = a + b;
if (c) {...}

No combination occurs between "add" and "comparesi" insn. I was expecting to 
see my "add_and_compare" pattern.
The resulting assembler is 
addk
cmp
jmp.if
instead of
add
jmp.if

Do someone see why combination fails ? (gcc 4.5.2)

Thanks,

Selim


add and compare combination

2011-12-15 Thread BELBACHIR Selim
Hi,

I'd like to know if there a way to express 'add' and 'compare' insn so that the 
combiner transform it in and 'add_and_compare' insn.

I watch arm backend and it seems possible when I look at 'addsi3', 'cbranchsi4' 
and '*addsi3_compare0'.

In my backend I have written the following insn/expand :

(define_expand "addsi3"
  [(set (match_operand:SI  0 "register_operand" "")
(plus:SI (match_operand:SI 1 "general_operand" "")
(match_operand:SI 2 "off1post_general_op" "")))]
   ""
   ""
)

(define_insn "add_and_compare"
  [(set (reg:CC CCI_REG)
(compare:CC
  (plus:SI
(match_operand:SI 1 "register_operand" "%r")
(match_operand:SI 2 "register_operand" "r"))
  (const_int 0)))
   (set (match_operand:SI 0 "register_operand"  "=r")
  (plus:SI
(match_dup 1)
(match_dup 2)))]
   ""
   "add %1,%2,%0"
)

(define_insn "add"
  [(set (match_operand:SI 0 "register_operand"  "=r")
  (plus:SI
(match_operand:SI 1 "register_operand" "%r")
(match_operand:SI 2 "register_operand" "r")))]
   ""
   "addk %1,%2,%0"
)

(define_expand "cbranchsi4"
  [(set (pc) 
(if_then_else (match_operator 0 "comparison_operator"
   [(match_operand:SI 1 "register_operand" "")
(match_operand:SI 2 "register_operand" "")])
(label_ref (match_operand 3 "" ""))
(pc)))]
  
  {
emit_insn(gen_comparesi (operands[1], operands[2]));
  
operands[1] = gen_rtx_REG (CCmode, CCI_REG);
operands[2] = const0_rtx;
  }
)

(define_insn "comparesi"
  [(set (reg:CC CCI_REG)
(compare:CC
  (match_operand:SI 0 "register_operand" "r")
  (match_operand:SI 1 "register_operand" "r")))]
  ""
  "cmp %1,%0"
)

(define_insn "jmpifsi"
  [(set (pc) 
(if_then_else (match_operator 0 "comparison_operator"
  [(reg:CC CCI_REG) (const_int 0)])
(label_ref (match_operand 1 "" ""))
(pc)))]
  ""
  "jmp.if %c0 %1"
)

When I compile :

c = a + b;
if (c) {...}

No combination occurs between "add" and "comparesi" insn. I was expecting to 
see my "add_and_compare" pattern.
The resulting assembler is 
addk
cmp
jmp.if
instead of
add
jmp.if

Do someone see why combination fails ? (gcc 4.5.2)

Thanks,

Selim


RE: dse2 remove wrong insn

2011-12-12 Thread BELBACHIR Selim
Everything seems good when I use a union instead of "*((int *)(&af))".

But I think that "*((int *)(&af))" is a valid syntax to get the integer 
representation of my floating point value (in my test case 0x3F80 for 1.0f 
in IEEE-754). It may be target dependant but I think it should work on target 
having 32 bits float and integer (and IEEE754 compliance).

I have gone on my debugging and I found what was wrong in my backend. I had 
STACK_POINTER_REGNUM=$C0, ARG_POINTER_REGNUM=$C1, FRAME_POINTER_REGNUM=$C0, no 
reg elimination macro, and prolog/epilog in adequacy. When I replaced my 
FRAME_POINTER_REGNUM by its own $C2 reg (i.e. a different value than 
STACK_POINTER_REGNUM) and added reg elimination macros the problem in dse2 pass 
disappeared (without adding unnecessary frame pointer in the asm output).
I have done this because looking as dse2.c I saw that some optimization was 
dealing with frame pointer and I was unsure of the correctness of the macro 
defining my ABI.

Are there requirement in dse2 pass according to FRAME_POINTER_REGNUM and 
STACK_POINTER_REGNUM definition ? Does my initial definition of 
FRAME_POINTER_REGNUM was totally dumb ? I don't know ...

Selim


-Message d'origine-
De : gcc-ow...@gcc.gnu.org [mailto:gcc-ow...@gcc.gnu.org] De la part de Andrew 
Haley
Envoyé : vendredi 9 décembre 2011 18:37
À : gcc@gcc.gnu.org
Objet : Re: dse2 remove wrong insn

On 12/09/2011 03:05 PM, BELBACHIR Selim wrote:
> int main() {
>   int x; 
>   float af;
>   ff(&x);
>   af = f2(1.0f);
>   return *((int *)(&af));
> }

Please try this again, but with a union rather than a pointer
cast.  I don't think this code is legal C.

Andrew.


dse2 remove wrong insn

2011-12-09 Thread BELBACHIR Selim
Hi,

I'm still working on a new gcc-4.5.2 backend for a private processor.
I encountered a strange behavior and I'm unable to find what causes this 
behavior.
As an overview, it seems that dse2 pass removes insn where it should not (optim 
-O2, -O3)

Here is the code giving me headachs which returns 0 when it should return 
0x3F80 (hex representation of 1.0f) :

void f1(int *ret2) {
  *ret2 = 2;
}

float f2(float par1) {
  return par1;
}

void (*ff)() = f1;

int main() {
  int x; 
  float af;
  ff(&x);
  af = f2(1.0f);
  return *((int *)(&af));
}

When I try to simplify this sample code further, the problem disappear even if 
apparenlty there is no relation between the f2 call and the ff call...


I watched the rtl dump and here is an extract of the interesting part dealing 
with the *((int *)(&af)) with f2 previously inlined (-O2 -O3) :


* in expand dump :

LC0->$72 
The 1.0f constant (LC0) is in data section.
Its a normal behavior because I have to insn to load a constant in $FP regs.
Hence I have to load the address of LC0 first.
(insn 9 8 10 3 (set:SI (reg:SI 72)
   (symbol_ref/u:SI ("*.LC0") [flags 0x2])) -1 (nil))

M($72)->$73
Memory pointing LC0 is loaded into reg 73
(insn 10 9 11 3 (set:SF (reg:SF 73)
(mem:SF (reg:SI 72) [0 S4 A32])) -1 (nil))

$73->M($62+4)
reg 73 moved into mem(stack+4).
(There are no memory to memory moves so using the temp reg 73 to move M($72) to 
M($62+4) is normal)
(insn 11 10 12 3 (set:SF (mem/c/i:SF (plus:SI (reg/f:SI 62 virtual-stack-vars)
  (const_int 4 [0x4])) [3 af+0 S4 
A32])
 (reg:SF 73)) -1 (nil))


$62+4->$75
mem(stack+4) moved to reg 75
(insn 12 11 13 3 (set (reg:SI 75)
  (plus:SI (reg/f:SI 62 virtual-stack-vars)
   (const_int 4 [0x4]

M($75)->76
reg 75 to reg 76
(insn 13 12 14 3 (set (reg:SI 76)
  (mem:SI (reg:SI 75) [4 S4 A32])) -1 (nil))

$76->$69
reg 76 to reg 69 which is the fixed return register
(I don't know why insn 12 don't move directly to reg 69... nevertheless it's 
correct)
(insn 14 13 15 3  (set (reg:SI 69 [  ])
   (reg:SI 76)) -1 (nil))






* in pro_and_epilogue dump (just before dse2) :

$C0+8->$C3
(insn 24 12 27 2  (set (reg/f:SI 3 $C3 [77])
   (plus:SI (reg/f:SI 0 $C0)
(const_int 8 [0x8]

[...]

LC0->$C2
(insn 9 8 29 2 (set:SI (reg/f:SI 2 $C2 [72])
   (symbol_ref/u:SI ("*.LC0") [flags 0x2])) 1 
{movsi_internal} (expr_list:REG_EQUIV (symbol_ref/u:SI ("*.LC0") [flags 0x2])
(nil)))

M($C2)->$FP1
(insn 29 9 11 2 (set (reg:SF 41 $FP1)
 (mem:SF (reg/f:SI 2 $C2 [72]) [0 S4 A32])) 10 
{movsf_internal} (nil))

$FP1->M($C0+12)
(insn 11 29 13 2 (set:SF (mem/c/i:SF (plus:SI (reg/f:SI 0 $C0)
 (const_int 12 [0xc])) [3 af+0 S4 A32])
 (reg:SF 41 $FP1)) 10 {movsf_internal} (nil))

M($C3+4)->$R0
(insn 13 11 21 2 (set (reg/i:SI 16 $R0)
  (mem:SI (plus:SI (reg/f:SI 3 $C3 [77])
   (const_int 4 [0x4])) [4 S4 A32])) 1 
{movsi_internal} (nil))

Every thing seems normal except the fact that $FP1 is moved in M($C0+12) and 
then the stored value is read with M($C3+4) where $C3=$C0+8.
This is due to optimisation (factorization) done during previous passes with 
the code before inline f2 call.





* in pro_ dse2_epilogue dump (we die here) :

$C0+8->$C3
(insn 24 12 27 2  (set (reg/f:SI 3 $C3 [77])
   (plus:SI (reg/f:SI 0 $C0)
(const_int 8 [0x8]

M($C3+4)->$R0
(insn 13 8 21 2 (set (reg/i:SI 16 $R0)
 (mem:SI (plus:SI (reg/f:SI 3 $C3 [77])
  (const_int 4 [0x4])) [4 S4 A32])) 1 
{movsi_internal} (expr_list:REG_DEAD (reg/f:SI 3 $C3 [77])
(nil)))





insn 9, 29 and 11 have been deleted ! :)
Here is what the dump says concerning insn 9, 29, 11 and 13


**scanning insn=9
mems_found = 0, cannot_delete = true

**scanning insn=29
  mem: (reg/f:SI 2 $C2 [72])

   after canon_rtx address: (reg/f:SI 2 $C2 [72])

   after cselib_expand address: (symbol_ref/u:SI ("*.LC0") [flags 0x2])

   after canon_rtx address: (symbol_ref/u:SI ("*.LC0") [flags 0x2])
  gid=1 offset=0
 processing const load gid=1[0..4)
mems_found = 0, cannot_delete = true

**scanning insn=11
  mem: (plus:SI (reg/f:SI 0 $C0)
(const_int 12 [0xc]))

   after canon_rtx address: (plus:SI (reg/f:SI 0 $C0)
(const_int 12 [0xc]))
  gid=2 offset=12
 processing const base store gid=2[12..16)
mems_found = 1, cannot_delete = false

**scanning insn=13
  mem: (plus:SI (reg/f:SI 3 $C3 [77])
(const_int 4 [0x4]))

   after canon_rtx address: (plus:SI (reg/f:SI 3 $C3 [77])
(const_int 4 [0x4]))

   after cselib_expand address: (plus:SI (reg/f:SI 3 $C3 [77])
(const_int 4 [0

maddsidi4 detection

2011-11-22 Thread BELBACHIR Selim
Hi,

I'm trying to define the standard pattern maddsidi4. To do this I wrote this in 
my backend (gcc4.5.2) :

 (define_insn "maddsidi4"
  [(set (match_operand:DI 0 "register_operand" "=a")
(plus:DI
  (mult:DI
(sign_extend:DI (match_operand:SI 1 "general_operand"  "%g"))
(sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))
  (match_operand:DI 3 "register_operand"   " 0")))]
  ""
  "mulacc %2,%1,%0";
 )

('a' constraints is for accumulator registers)
(the movdi standard pattern defines the moves from and to accumulator registers)


When I compile the following code, mulacc is properly emitted :

void test_maddsidi4(int a, int b, long long * c)
{
  *c += (long long)a*(long long)b;
}


But when I write the following code, (mulsidi3 + adddi3) is chosen instead of 
maddsi4:

void maddsidi4_alt(int a, int b, long long * c)
{
  *c = (long long)a*(long long)b + (*c);
}

I tried in debug mode to figure out why maddsi4 is ignore in the last case. I 
found in expr.c file, in 'expand_expr_real_2' function and in 'PLUS_EXPR' 
switch case that instead of encountering a MULT_EXPR following the PLUS_EXPR, 
an INDIRECT_REF is encountered. This seems quite logical given the '+(*c)' in 
my test.

I'm quite surprised that the multiplication/addition detection is so 
restrictive. Is there a way to enhance the mul/add detection without patching 
expr.c ? Someone else has certainly met the same problem :) Feel free to send 
me the trick or patch :)

Regards,

Selim






Building cross gnat + minimal RTS

2011-11-15 Thread BELBACHIR Selim
Hi,

I'm trying to build a gnat cross compiler based on gcc 4.5.2 for my private 
target (named prism). To do this, I'm using a native gnat-6.4.2 (containing gcc 
4.5.2).

I want the minimal amount of lib and runtime so I presume that I nearly only 
need to provide 'system.ads'. (I will add secondary stack management later).

I don't find the standard procedure to build my cross gnat + minimal RTS.


First I configure this way :

configure --prefix=$(INSTALLDIR) --target=prism --disable-nls 
--enable-languages=c,ada --with-gmp=$(INSTALLDIR) --with-mpfr=$(INSTALLDIR) 
--with-mpc=$(INSTALLDIR) LDFLAGS="-static" --without-libiconv-prefix 
--disable-libmudflap --disable-libffi --disable-libstdcxx-pch --disable-libada 
--disable-libgcc --disable-libssp --enable-checking=release

Then I simply do :

make
make install

but it ends like this :

You must first build the GNAT library: make gnatlib
make[5]: *** [../stamp-gnatlib-rts] Error 1
make[4]: *** [install-gnatlib] Error 2

(I though that --disable-libada option would disable the need for libs...)

At this point my new cross compiler provide the following error when I try to 
compile a simple adb :

fatal error, run-time library not installed correctly
cannot locate file system.ads
compilation abandoned

If I copy manually my system.ads into the right install dir (taking example on 
another working cross compiler), my cross compile seems to work.



I browsed the source directory gcc/ada, and I tried to insert the following 
lines in gcc/ada/gcc-interface/Makefile.in hoping it will copy my 
system-prism.ads automatically during build process :

ifeq ($(strip $(filter-out %prism,$(arch))),)
  LIBGNAT_TARGET_PAIRS = \
  system.ads

gnat cross compilation

2011-10-26 Thread BELBACHIR Selim
Hi,

Is it possible to compile a gnat cross compiler based on gcc 4.5.2 
using my pre-installed gnat native compiler based on gcc 3.4.6 ? Or should I 
try to build my own local native compiler based on gcc 4.5.2 ?

I ask the question because for the moment, I'm stuck with the following error 
during the make :

a-except.adb:45:01: warning: unrecognized pragma "Compiler_Unit"

And I think that "Compiler_Unit" may no exist in gcc 3.4.6...


Regards,

Selim




arithmetic standard pattern using only memory_operand

2011-10-21 Thread BELBACHIR Selim
Hi,

My target has arithmetic instruction whose operands can ONLY be memory 
(offseted, post/pre inc, ...).

For example 'add' can only have a memory operand as its first operand :

add mem($C1), $C2, $C3



I tried to simply write the addsi3 pattern with using memory_operand as 
predicate for operand 2 but gcc often (always?) tries to use a register instead 
of memory and finally send the error message : 

unrecognizable insn :
set (reg:SI 0) (plus:SI (reg SI 1) (reg SI 2))


Is it possible to define arithmetic standard parttern with operands matched by 
memory_operand only ? How ?
Maybe I forgot a important MACRO in may .h ?


Regards,

Selim



Instruction scheduler question

2011-10-07 Thread BELBACHIR Selim
Hello,

I'm trying to express the instruction latency time constraints of a private 
processor.


* Overview :

Two cycles are necessary between a comparison instruction and a conditionnal 
jump instruction (GSR is updated 2 cycles after comparison).

If nothing better than 'nop' can be used between compare and jump the asm shall 
be :

 cmp $A $B
 nop
 nop
 jmpifeq $C

I copied mips method to insert 'nop' (using TARGET_MACHINE_DEPENDENT_REORG 
macro).


* Automaton definition :

(define_cpu_unit "ctrl")
(define_cpu_unit "readmem")
(define_cpu_unit "gsr")

;; To express that the compare result (gsr) will only be available in 3 cycles
(define_insn_reservation "COMPARE" 3 
  (eq_attr "type" "compare")
  "gsr+ctrl,gsr*2")

;; To express that jump uses the gsr result
(define_insn_reservation "JUMP" 1 
  (eq_attr "type" "jump")
  "ctrl+gsr")

My compare insn has attribute type = 'compare' and my jump insn has attribute 
type = 'jump'


* Problem :

I never see instruction other than 'nop' between the compare and jump 
instructions. 
For example, I see :

(asm result)

load d($C2),$R1     <--1st operand for comparison ctrl,readmem,nothing
loadi 0,$C4     <- 2nd operand for comparison ctrl,nothing
load d($C2+4),$R2   <--no data dependancies   ctrl,readmem,nothing
cmp $C4,$R1   (gsr+ctrl),gsr*2
nop
nop
jmpifeq .L5   (ctrl+gsr)    

(.sched2)

;;   --- Region Dependences --- b 2 bb 0
;;  insn  code    bb   dep  prio  cost   reservation
;;        --   ---       ---
;;   18 0 2    14 7 3   ctrl,readmem,nothing  : 23 22 19
;;   19 0 2    15 3 3   ctrl,readmem,nothing  : 23
;;   81 0 2 1 6 2   ctrl,nothing      : 23 22
;;   22    10 2 3 4 3   (gsr+ctrl),gsr*2      : 23
;;   23 9 2    20 1 1   (ctrl+gsr)    :


;;  dependencies resolved: insn 81
;;  Ready-->Q: insn 81: queued for 1 cycles.
;;  tick updated: insn 81 into queue with cost=1
;;  dependencies resolved: insn 18
;;  tick updated: insn 18 into ready
;;  Ready list (t =  18):    18:17
;;  Q-->Ready: insn 81: moving to ready without stalls
;;  Ready list after queue_to_ready:    81:19  18:17
;;  Ready list after ready_sort:    81:19  18:17
;;  Ready list (t =  19):    81:19  18:17
;;   19-->    18 $R1=[$C2] :ctrl,datar,nothing
;;  dependencies resolved: insn 19
;;  tick updated: insn 19 into ready
;;  Ready list (t =  19):    19:18  81:19
;;  Ready list after queue_to_ready:    19:18  81:19
;;  Ready list after ready_sort:    19:18  81:19
;;  Ready list (t =  20):    19:18  81:19
;;   20-->    81 $C4=0x0   :ctrl,nothing
;;  dependencies resolved: insn 22
;;  Ready-->Q: insn 22: queued for 2 cycles.
;;  tick updated: insn 22 into queue with cost=2
;;  Ready list (t =  20):    19:18
;;  Ready list after queue_to_ready:    19:18
;;  Ready list after ready_sort:    19:18
;;  Ready list (t =  21):    19:18
;;   21-->    19 $R2=[$C2+0x4] :ctrl,datar,nothing
;;  Ready list (t =  21):
;;  Q-->Ready: insn 22: moving to ready without stalls
;;  Ready list after queue_to_ready:    22:20
;;  Ready list after ready_sort:    22:20
;;  Ready list (t =  22):    22:20
;;   22-->    22 {$GSR=cmp($R1,$C4);clobber $R3;}  :(gsr+ctrl),gsr*2
;;  dependencies resolved: insn 23
;;  Ready-->Q: insn 23: queued for 3 cycles.
;;  tick updated: insn 23 into queue with cost=3
;;  Ready list (t =  22):
;;  Q-->Ready: insn 23: moving to ready with 2 stalls
;;  Ready list after queue_to_ready:    23:21
;;  Ready list after ready_sort:    23:21
;;  Ready list (t =  25):    23:21
;;   25-->    23 pc={($GSR==0x0)?L110:pc}  :(ctrl+gsr)
;;  Ready list (t =  25):
;;  Ready list (final):


The 'load d($C2+4),$R2' instruction seems a good canditate to be moved between 
compare and jump instruction because there are no data dependencies with 
compare/jump instructions and no reservation collision.

Can someone explain me how to obtain the following assembler ? : 

load d($C2),$R1     
loadi 0,$C4     
cmp $C4,$R1
load d($C2+4),$R2
nop
jmpifeq .L5   

 Regards,

  Selim Belbachir



RE: postreload problem using reload_inm and SECONDARY_RELOAD macros

2011-09-15 Thread BELBACHIR Selim
further hints :

The immediate which gcc wants to move in R_REGS is a (const_int 8) as described 
in the error message below :

arithmetic.c:197: error: insn does not satisfy its constraints:
(insn 1505 903 1506 0 (set (reg:SI 25 $R9)
(const_int 8 [0x8])) 0 {movsi_internal} (nil)
(nil))
arithmetic.c:197: internal compiler error: in 
reload_cse_simplify_operands, at postreload.c:391


So I added some debug trace in function 'my_secondary_input_reload_class' to 
understand why (const_int 8) is not reloaded to C_REGS.

'my_secondary_input_reload_class' is called several times but never with rtl 
expression (const_int 8).

I also checked 'my_preferred_reload_class' function and I don't see expression 
(const_int 8).

Selim



RE: postreload problem using reload_inm and SECONDARY_RELOAD macros

2011-09-14 Thread BELBACHIR Selim
Yes I know gcc 3.4.6 is quite old :) but the backend work has started on this 
version for bad reasons and now we plan to make something work (pass a few test 
cases) before migrating to last gcc 4 version.

Concerning REGISTER_MOVE_COST, I don't know what can be fixed with it.
The 3 params of REGISTER_MOVE_COST are (machine_mode mode, regclass from, 
reg_class to).
So I can only write cost for register to register moves.
I don't see any suitable macro to specify immediate to register moves. (in 
gcc3.4.6 internals )

Nevertheless, the REGISTER_MOVE_COST is defined with costs 3 for all valid 
moves (C_REGS <-> R_REGS).

Is there a way to prevent totally the allocation of a hard register in specific 
context using 'costs'?

-Message d'origine-
De : Ian Lance Taylor [mailto:i...@google.com] 
Envoyé : mercredi 14 septembre 2011 15:40
À : BELBACHIR Selim
Cc : gcc@gcc.gnu.org
Objet : Re: postreload problem using reload_inm and SECONDARY_RELOAD macros

BELBACHIR Selim  writes:

> I'm writing a backend for gcc3.4.6 and I'm a bit confused about reload passes.

You know gcc 3.4.6 is really old, right?

> I have no mean to express this limitation inside predicates (because
> pseudo register don't known in which hard register they will be
> allocated), reload pass create some moves from immediate to $R.  :

First guess would be REGISTER_MOVE_COST.

Ian


postreload problem using reload_inm and SECONDARY_RELOAD macros

2011-09-14 Thread BELBACHIR Selim
Hi,

I'm writing a backend for gcc3.4.6 and I'm a bit confused about reload passes.



-> my constraints :

'b' = arithmetic/logical unit register ($R, class R_REGS)
'c' = counter register ($C, class C_REGS)
'v' = memory with several special constraint (also described in predicate 
my_mem_or_reg_operand)



-> movsi expand/insn :

 (define_insn "movsi_internal"
  [(set    
  (match_operand:SI 0 "my_mem_or_reg_operand" "=v,v,c,b,b ")
  (match_operand: SI 1 "general_operand" "c,b,v,v,i "))]
  ""
  "@
  mov %1,%0
  [.]
  loadi %1,%0"
)

 (define_expand "movsi"
  [(set    
  (match_operand:SI 0 "general_operand" "")
  (match_operand:SI 1 "general_operand" ""))]
  ""
  {
 /* Handle Memory to Memory and immediate to memory movs */
 if (((GET_CODE (operands[1]) == MEM) || immediate_operand (operands[1], 
SImode))
  && (GET_CODE(operands[0])== MEM) )
 { 
    operands[1] = force_reg(SImode,operands[1]);
 }
  }
)

Note there is no instruction to move immediate to $R regs ('b' constraint) but 
there is one to move immediate to $C regs ('c' constraint).

I have no mean to express this limitation inside predicates (because pseudo 
register don't known in which hard register they will be allocated), reload 
pass create some moves from immediate to $R.  :


arithmetic.c:197: error: insn does not satisfy its constraints:
(insn 1505 903 1506 0 (set (reg:SI 25 $R9)
    (const_int 8 [0x8])) 0 {movsi_internal} (nil)
    (nil))
arithmetic.c:197: internal compiler error: in 
reload_cse_simplify_operands, at postreload.c:391





So, I read the doc :) and figured out how to control the reload pass. I added 2 
MACROs and the reload_insi expand :

#define PREFERRED_RELOAD_CLASS(X,CLASS) my_preferred_reload_class(X,CLASS)
#define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, X) 
my_secondary_input_reload_class (CLASS, MODE, X)

enum reg_class my_preferred_reload_class(rtx x, enum reg_class rclass)
{
   if (GET_CODE(x) == CONST_INT || GET_CODE(x) == CONST_DOUBLE) {
   if (rclass == GENERAL_REGS) {
  return C_REGS;
   }
   else if (rclass == R_REGS) {
  return NO_REGS; /* put the constant in memory */
   }
   }
   return rclass;
}

enum reg_class my_secondary_input_reload_class(enum reg_class rclass, enum 
machine_mode mode, rtx x)
{
  if ((GET_CODE(x) == CONST_INT || GET_CODE(x) == CONST_DOUBLE) && rclass == 
R_REGS) {
 return C_REGS; /* use C_REGS for clobber in reload_insi */
  }
  return NO_REGS;
}

(define_expand "reload_insi"
  [(set 
  (match_operand:SI 0 "register_operand" "=b")
      (match_operand:SI 1 "immediate_operand" "i"))
   (clobber (match_operand:SI 2 "register_operand" "=c"))]
"
{    
   emit_insn(gen_rtx_SET(SImode, operands[2], operands[1]));
   emit_insn(gen_rtx_SET(SImode, operands[0], operands[2]));
   DONE;
}
)

Theses MACROs and insn do not solve my problem and the forbidden move keeps on 
being emitted.
Did I misunderstood something ? A my doing something illegal ? Should I do 
things differently?
(A printf in my reload_insi shows that this expand is never called.)

    Thank you for your help.