@@ -23,12 +23,12 @@ local _M = { _info = _info }
23
23
local type , tonumber , pairs , ipairs = type , tonumber , pairs , ipairs
24
24
local assert , setmetatable , rawget = assert , setmetatable , rawget
25
25
local _s = string
26
- local sub , format , byte , char = _s . sub , _s .format , _s .byte , _s .char
26
+ local format , byte , char = _s .format , _s .byte , _s .char
27
27
local match , gmatch , gsub = _s .match , _s .gmatch , _s .gsub
28
28
local concat , sort , insert = table.concat , table.sort , table.insert
29
29
local bit = bit or require (" bit" )
30
30
local band , shl , shr , sar = bit .band , bit .lshift , bit .rshift , bit .arshift
31
- local ror , tohex = bit .ror , bit .tohex
31
+ local ror , tohex , tobit = bit .ror , bit .tohex , bit . tobit
32
32
33
33
-- Inherited tables and callbacks.
34
34
local g_opt , g_arch
@@ -39,7 +39,8 @@ local wline, werror, wfatal, wwarn
39
39
local action_names = {
40
40
" STOP" , " SECTION" , " ESC" , " REL_EXT" ,
41
41
" ALIGN" , " REL_LG" , " LABEL_LG" ,
42
- " REL_PC" , " LABEL_PC" , " IMM" , " IMM6" , " IMM12" , " IMM13W" , " IMM13X" , " IMML" ,
42
+ " REL_PC" , " LABEL_PC" , " REL_A" ,
43
+ " IMM" , " IMM6" , " IMM12" , " IMM13W" , " IMM13X" , " IMML" , " IMMV" ,
43
44
" VREG" ,
44
45
}
45
46
@@ -311,7 +312,7 @@ local function parse_number(n)
311
312
local code = loadenv (" return " .. n )
312
313
if code then
313
314
local ok , y = pcall (code )
314
- if ok then return y end
315
+ if ok and type ( y ) == " number " then return y end
315
316
end
316
317
return nil
317
318
end
@@ -575,14 +576,14 @@ local function parse_load_pair(params, nparams, n, op)
575
576
end
576
577
577
578
local function parse_label (label , def )
578
- local prefix = sub (label , 1 , 2 )
579
+ local prefix = label : sub (1 , 2 )
579
580
-- =>label (pc label reference)
580
581
if prefix == " =>" then
581
- return " PC" , 0 , sub (label , 3 )
582
+ return " PC" , 0 , label : sub (3 )
582
583
end
583
584
-- ->name (global label reference)
584
585
if prefix == " ->" then
585
- return " LG" , map_global [sub (label , 3 )]
586
+ return " LG" , map_global [label : sub (3 )]
586
587
end
587
588
if def then
588
589
-- [1-9] (local label definition)
@@ -600,8 +601,11 @@ local function parse_label(label, def)
600
601
if extname then
601
602
return " EXT" , map_extern [extname ]
602
603
end
604
+ -- &expr (pointer)
605
+ if label :sub (1 , 1 ) == " &" then
606
+ return " A" , 0 , format (" (ptrdiff_t)(%s)" , label :sub (2 ))
607
+ end
603
608
end
604
- werror (" bad label `" .. label .. " '" )
605
609
end
606
610
607
611
local function branch_type (op )
@@ -895,14 +899,14 @@ end
895
899
896
900
-- Handle opcodes defined with template strings.
897
901
local function parse_template (params , template , nparams , pos )
898
- local op = tonumber (sub (template , 1 , 8 ), 16 )
902
+ local op = tonumber (template : sub (1 , 8 ), 16 )
899
903
local n = 1
900
904
local rtt = {}
901
905
902
906
parse_reg_type = false
903
907
904
908
-- Process each character.
905
- for p in gmatch (sub (template , 9 ), " ." ) do
909
+ for p in gmatch (template : sub (9 ), " ." ) do
906
910
local q = params [n ]
907
911
if p == " D" then
908
912
op = op + parse_reg (q , 0 ); n = n + 1
@@ -944,8 +948,14 @@ local function parse_template(params, template, nparams, pos)
944
948
945
949
elseif p == " B" then
946
950
local mode , v , s = parse_label (q , false ); n = n + 1
951
+ if not mode then werror (" bad label `" .. q .. " '" ) end
947
952
local m = branch_type (op )
948
- waction (" REL_" .. mode , v + m , s , 1 )
953
+ if mode == " A" then
954
+ waction (" REL_" .. mode , v + m , format (" (unsigned int)(%s)" , s ))
955
+ actargs [# actargs + 1 ] = format (" (unsigned int)((%s)>>32)" , s )
956
+ else
957
+ waction (" REL_" .. mode , v + m , s , 1 )
958
+ end
949
959
950
960
elseif p == " I" then
951
961
op = op + parse_imm12 (q ); n = n + 1
@@ -1050,23 +1060,50 @@ map_op[".label_1"] = function(params)
1050
1060
if not params then return " [1-9] | ->global | =>pcexpr" end
1051
1061
if secpos + 1 > maxsecpos then wflush () end
1052
1062
local mode , n , s = parse_label (params [1 ], true )
1053
- if mode == " EXT" then werror (" bad label definition" ) end
1063
+ if not mode or mode == " EXT" then werror (" bad label definition" ) end
1054
1064
waction (" LABEL_" .. mode , n , s , 1 )
1055
1065
end
1056
1066
1057
1067
---- --------------------------------------------------------------------------
1058
1068
1059
1069
-- Pseudo-opcodes for data storage.
1060
- map_op [ " .long_* " ] = function (params )
1070
+ local function op_data (params )
1061
1071
if not params then return " imm..." end
1072
+ local sz = params .op == " .long" and 4 or 8
1062
1073
for _ ,p in ipairs (params ) do
1063
- local n = tonumber (p )
1064
- if not n then werror (" bad immediate `" .. p .. " '" ) end
1065
- if n < 0 then n = n + 2 ^ 32 end
1066
- wputw (n )
1074
+ local imm = parse_number (p )
1075
+ if imm then
1076
+ local n = tobit (imm )
1077
+ if n == imm or (n < 0 and n + 2 ^ 32 == imm ) then
1078
+ wputw (n < 0 and n + 2 ^ 32 or n )
1079
+ if sz == 8 then
1080
+ wputw (imm < 0 and 0xffffffff or 0 )
1081
+ end
1082
+ elseif sz == 4 then
1083
+ werror (" bad immediate `" .. p .. " '" )
1084
+ else
1085
+ imm = nil
1086
+ end
1087
+ end
1088
+ if not imm then
1089
+ local mode , v , s = parse_label (p , false )
1090
+ if sz == 4 then
1091
+ if mode then werror (" label does not fit into .long" ) end
1092
+ waction (" IMMV" , 0 , p )
1093
+ elseif mode and mode ~= " A" then
1094
+ waction (" REL_" .. mode , v + 0x8000 , s , 1 )
1095
+ else
1096
+ if mode == " A" then p = s end
1097
+ waction (" IMMV" , 0 , format (" (unsigned int)(%s)" , p ))
1098
+ waction (" IMMV" , 0 , format (" (unsigned int)((unsigned long long)(%s)>>32)" , p ))
1099
+ end
1100
+ end
1067
1101
if secpos + 2 > maxsecpos then wflush () end
1068
1102
end
1069
1103
end
1104
+ map_op [" .long_*" ] = op_data
1105
+ map_op [" .quad_*" ] = op_data
1106
+ map_op [" .addr_*" ] = op_data
1070
1107
1071
1108
-- Alignment pseudo-opcode.
1072
1109
map_op [" .align_1" ] = function (params )
0 commit comments