# comment => "any comment for constructor",
# reg_req => { in => [ "reg_class|register" ], out => [ "reg_class|register|in_rX" ] },
# cmp_attr => "c source code for comparing node attributes",
+# outs => { "out1", "out2" } # optional, creates pn_op_out1, ... consts
+# ins => { "in1", "in2" } # optional, creates n_op_in1, ... consts
+# mode => "mode_Iu" # optional, predefines the mode
# emit => "emit code with templates",
-# attr => "attitional attribute arguments for constructor"
-# init_attr => "emit attribute initialization template"
+# attr => "attitional attribute arguments for constructor",
+# init_attr => "emit attribute initialization template",
# rd_constructor => "c source code which constructs an ir_node"
+# hash_func => "name of the hash function for this operation",
# latency => "latency of this operation (can be float)"
# attr_type => "name of the attribute struct",
# },
$mode_fpa = "mode_E";
# register types:
-# 0 - no special type
-# 1 - caller save (register must be saved by the caller of a function)
-# 2 - callee save (register must be saved by the called function)
-# 4 - ignore (do not assign this register)
-# 8 - emitter can choose an arbitrary register of this class
-# 16 - the register is a virtual one
-# 32 - register represents a state
+$normal = 0; # no special type
+$caller_save = 1; # caller save (register must be saved by the caller of a function)
+$callee_save = 2; # callee save (register must be saved by the called function)
+$ignore = 4; # ignore (do not assign this register)
+$arbitrary = 8; # emitter can choose an arbitrary register of this class
+$virtual = 16; # the register is a virtual one
+$state = 32; # register represents a state
# NOTE: Last entry of each class is the largest Firm-Mode a register can hold
%reg_classes = (
gp => [
- { "name" => "r0", "type" => 1 },
- { "name" => "r1", "type" => 1 },
- { "name" => "r2", "type" => 1 },
- { "name" => "r3", "type" => 1 },
- { "name" => "r4", "type" => 2 },
- { "name" => "r5", "type" => 2 },
- { "name" => "r6", "type" => 2 },
- { "name" => "r7", "type" => 2 },
- { "name" => "r8", "type" => 2 },
- { "name" => "r9", "type" => 2 },
- { "name" => "r10", "type" => 2 },
- { "name" => "r11", "type" => 2 },
- { "name" => "r12", "type" => 4 | 2 }, # reserved for linker
- { "name" => "sp", "type" => 4 | 2 }, # this is our stack pointer
- { "name" => "lr", "type" => 2 | 1 }, # this is our return address
- { "name" => "pc", "type" => 4 | 2 }, # this is our program counter
- { name => "gp_UKNWN", type => 4 | 8 | 16 }, # we need a dummy register for Unknown nodes
+ { "name" => "r0", "type" => $caller_save },
+ { "name" => "r1", "type" => $caller_save },
+ { "name" => "r2", "type" => $caller_save },
+ { "name" => "r3", "type" => $caller_save },
+ { "name" => "r4", "type" => $callee_save },
+ { "name" => "r5", "type" => $callee_save },
+ { "name" => "r6", "type" => $callee_save },
+ { "name" => "r7", "type" => $callee_save },
+ { "name" => "r8", "type" => $callee_save },
+ { "name" => "r9", "type" => $callee_save },
+ { "name" => "r10", "type" => $callee_save },
+ { "name" => "r11", "type" => $callee_save },
+ { "name" => "r12", "type" => $ignore | $callee_save }, # reserved for linker
+ { "name" => "sp", "type" => $ignore | $callee_save }, # this is our stack pointer
+ { "name" => "lr", "type" => $callee_save | $caller_save }, # this is our return address
+ { "name" => "pc", "type" => $ignore | $callee_save }, # this is our program counter
+ { name => "gp_UKNWN", type => $ignore | $arbitrary | $virtual }, # we need a dummy register for Unknown nodes
{ "mode" => $mode_gp }
],
fpa => [
Shr => {
irn_flags => "R",
- comment => "construct Shr: Shr(a, b) = a >> b",
- reg_req => { "in" => [ "gp", "gp" ], "out" => [ "in_r1" ] },
+ comment => "construct Shr: Shr(a, b) = a >>u b",
+ reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
emit => '. mov %D0, %S0, lsr %S1'
},
Shrs => {
irn_flags => "R",
- comment => "construct Shrs: Shrs(a, b) = a >> b",
- reg_req => { "in" => [ "gp", "gp" ], "out" => [ "in_r1" ] },
+ comment => "construct Shrs: Shrs(a, b) = a >>s b",
+ reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
emit => '. mov %D0, %S0, asr %S1'
},
-#RotR => {
-# irn_flags => "R",
-# comment => "construct RotR: RotR(a, b) = a ROTR b",
-# reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
-# emit => '. mov %D0, %S0, ror %S1 /* RotR(%S0, %S1) -> %D0, (%A1, %A2) */'
-## emit => '. ror %S0, %S1, %D0'
-#},
+Ror => {
+ irn_flags => "R",
+ comment => "construct Ror: Ror(a, b) = a <<r>> b",
+ reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
+ emit => '. mov %D0, %S0, ror %S1'
+},
#RotL => {
# irn_flags => "R",
attr_type => "arm_CondJmp_attr_t",
},
+TstBra => {
+ op_flags => "L|X|Y",
+ state => "pinned",
+ comment => "construct conditional branch: TST A, B && JMPxx LABEL",
+ mode => "mode_T",
+ attr => "int proj_num",
+ init_attr => "\tset_arm_CondJmp_proj_num(res, proj_num);",
+ reg_req => { "in" => [ "gp", "gp" ], "out" => [ "none", "none"] },
+ attr_type => "arm_CondJmp_attr_t",
+},
+
SwitchJmp => {
op_flags => "L|X|Y",
state => "pinned",
op_flags => "L|F",
irn_flags => "R",
state => "exc_pinned",
- comment => "construct Store: Store(ptr, val, mem) = ST ptr,val",
+ comment => "construct Store: Push 4 Registers = ST ptr,val",
reg_req => { "in" => [ "sp", "gp", "gp", "gp", "gp", "none" ], "out" => [ "gp", "none" ] },
emit => '. stmfd %S0!, {%S1, %S2, %S3, %S4}',
outs => [ "ptr", "M" ],
outs => [ "stack:I|S", "M" ],
},
-SubSP => {
+SubSPandCopy => {
#irn_flags => "I",
- comment => "construct Sub from stack pointer",
+ comment => "construct Sub from stack pointer and copy to Register",
reg_req => { in => [ "sp", "gp", "none" ], out => [ "in_r1", "gp", "none" ] },
ins => [ "stack", "size", "mem" ],
emit => ". sub %D0, %S0, %S1\n".