diff --git a/compiler/aasmtai.pas b/compiler/aasmtai.pas index a8ea8c81b0..28767a4117 100644 --- a/compiler/aasmtai.pas +++ b/compiler/aasmtai.pas @@ -273,7 +273,7 @@ interface top_shifterop : (shifterop : pshifterop); {$endif defined(arm) or defined(aarch64)} {$ifdef m68k} - top_regset : (regset:^tcpuregisterset); + top_regset : (dataregset,addrregset:^tcpuregisterset); {$endif m68k} {$ifdef jvm} top_single : (sval:single); @@ -2626,6 +2626,13 @@ implementation top_regset: dispose(regset); {$endif ARM} +{$ifdef m68k} + top_regset: + begin + dispose(dataregset); + dispose(addrregset); + end; +{$endif m68k} {$ifdef jvm} top_string: freemem(pcval); diff --git a/compiler/m68k/aasmcpu.pas b/compiler/m68k/aasmcpu.pas index 9b3be04d86..c6585a6492 100644 --- a/compiler/m68k/aasmcpu.pas +++ b/compiler/m68k/aasmcpu.pas @@ -40,6 +40,9 @@ type taicpu = class(tai_cpu_abstract_sym) opsize : topsize; + + procedure loadregset(opidx:longint; const dataregs,addrregs:tcpuregisterset); + constructor op_none(op : tasmop); constructor op_none(op : tasmop;_size : topsize); @@ -65,11 +68,11 @@ type constructor op_reg_reg_ref(op : tasmop;_size : topsize;_op1,_op2 : tregister; _op3 : treference); constructor op_const_reg_ref(op : tasmop;_size : topsize;_op1 : longint;_op2 : tregister;_op3 : treference); - constructor op_reg_regset(op: tasmop; _size : topsize; _op1: tregister;const _op2: tcpuregisterset); - constructor op_regset_reg(op: tasmop; _size : topsize;const _op1: tcpuregisterset; _op2: tregister); + constructor op_reg_regset(op: tasmop; _size : topsize; _op1: tregister;const _op2data,_op2addr: tcpuregisterset); + constructor op_regset_reg(op: tasmop; _size : topsize;const _op1data,_op1addr: tcpuregisterset; _op2: tregister); - constructor op_ref_regset(op: tasmop; _size : topsize; _op1: treference;const _op2: tcpuregisterset); - constructor op_regset_ref(op: tasmop; _size : topsize;const _op1: tcpuregisterset; _op2: treference); + constructor op_ref_regset(op: tasmop; _size : topsize; _op1: treference;const _op2data,_op2addr: tcpuregisterset); + constructor op_regset_ref(op: tasmop; _size : topsize;const _op1data,_op1addr: tcpuregisterset; _op2: treference); { this is for Jmp instructions } constructor op_cond_sym(op : tasmop;cond:TAsmCond;_size : topsize;_op1 : tasmsymbol); @@ -86,7 +89,6 @@ type function spilling_get_operation_type(opnr: longint): topertype;override; private - procedure loadregset(opidx:longint;const s:tcpuregisterset); procedure init(_size : topsize); { this need to be called by all constructor } end; @@ -168,7 +170,7 @@ type - procedure taicpu.loadregset(opidx:longint;const s:tcpuregisterset); + procedure taicpu.loadregset(opidx:longint; const dataregs,addrregs:tcpuregisterset); var i : byte; begin @@ -177,17 +179,19 @@ type begin if typ<>top_regset then clearop(opidx); - new(regset); - regset^:=s; + new(dataregset); + new(addrregset); + dataregset^:=dataregs; + addrregset^:=addrregs; typ:=top_regset; for i:=RS_D0 to RS_D7 do begin - if assigned(add_reg_instruction_hook) and (i in regset^) then + if assigned(add_reg_instruction_hook) and (i in dataregset^) then add_reg_instruction_hook(self,newreg(R_INTREGISTER,i,R_SUBWHOLE)); end; for i:=RS_A0 to RS_SP do begin - if assigned(add_reg_instruction_hook) and (i in regset^) then + if assigned(add_reg_instruction_hook) and (i in addrregset^) then add_reg_instruction_hook(self,newreg(R_ADDRESSREGISTER,i,R_SUBWHOLE)); end; end; @@ -377,42 +381,43 @@ type end; - constructor taicpu.op_ref_regset(op: tasmop; _size : topsize; _op1: treference;const _op2: tcpuregisterset); + constructor taicpu.op_ref_regset(op: tasmop; _size : topsize; _op1: treference;const _op2data,_op2addr: tcpuregisterset); Begin inherited create(op); init(_size); ops:=2; loadref(0,_op1); - loadregset(1,_op2); + loadregset(1,_op2data,_op2addr); end; - constructor taicpu.op_regset_ref(op: tasmop; _size : topsize;const _op1: tcpuregisterset; _op2: treference); + + constructor taicpu.op_regset_ref(op: tasmop; _size : topsize;const _op1data,_op1addr: tcpuregisterset; _op2: treference); Begin inherited create(op); init(_size); ops:=2; - loadregset(0,_op1); + loadregset(0,_op1data,_op1addr); loadref(1,_op2); End; - constructor taicpu.op_reg_regset(op: tasmop; _size : topsize; _op1: tregister;const _op2: tcpuregisterset); + constructor taicpu.op_reg_regset(op: tasmop; _size : topsize; _op1: tregister;const _op2data,_op2addr: tcpuregisterset); Begin inherited create(op); init(_size); ops:=2; loadreg(0,_op1); - loadregset(1,_op2); + loadregset(1,_op2data,_op2addr); end; - constructor taicpu.op_regset_reg(op: tasmop; _size : topsize;const _op1: tcpuregisterset; _op2: tregister); + constructor taicpu.op_regset_reg(op: tasmop; _size : topsize;const _op1data,_op1addr: tcpuregisterset; _op2: tregister); Begin inherited create(op); init(_size); ops:=2; - loadregset(0,_op1); + loadregset(0,_op1data,_op1addr); loadreg(1,_op2); End; diff --git a/compiler/m68k/ag68kgas.pas b/compiler/m68k/ag68kgas.pas index fde4755273..4cc892702c 100644 --- a/compiler/m68k/ag68kgas.pas +++ b/compiler/m68k/ag68kgas.pas @@ -229,12 +229,12 @@ interface hs:=''; for i:=RS_D0 to RS_D7 do begin - if i in o.regset^ then + if i in o.dataregset^ then hs:=hs+gas_regname(newreg(R_INTREGISTER,i,R_SUBWHOLE))+'/'; end; for i:=RS_A0 to RS_SP do begin - if i in o.regset^ then + if i in o.addrregset^ then hs:=hs+gas_regname(newreg(R_INTREGISTER,i,R_SUBWHOLE))+'/'; end; delete(hs,length(hs),1); diff --git a/compiler/m68k/ra68kmot.pas b/compiler/m68k/ra68kmot.pas index 01180ed15d..a8353e54ab 100644 --- a/compiler/m68k/ra68kmot.pas +++ b/compiler/m68k/ra68kmot.pas @@ -1283,10 +1283,11 @@ const r:Tregister; hl: tasmlabel; reg_one, reg_two: tregister; - regset: tcpuregisterset; + addrregset,dataregset: tcpuregisterset; p: pointer; begin - regset := []; + dataregset := []; + addrregset := []; tempstr := ''; case actasmtoken of { // Memory reference // } @@ -1477,21 +1478,28 @@ const if (actasmtoken = AS_SLASH) then begin r:=actasmregister; - if getregtype(r)<>R_INTREGISTER then + if getregtype(r)=R_ADDRESSREGISTER then + include(addrregset,getsupreg(r)) + else if getregtype(r)=R_INTREGISTER then + include(dataregset,getsupreg(r)) + else internalerror(200302191); - include(regset,getsupreg(r)); Consume(AS_SLASH); if actasmtoken = AS_REGISTER then begin While not (actasmtoken in [AS_SEPARATOR,AS_COMMA]) do begin case actasmtoken of - AS_REGISTER: begin - if getregtype(r)<>R_INTREGISTER then - internalerror(200302191); - include(regset,getsupreg(r)); - Consume(AS_REGISTER); - end; + AS_REGISTER: + begin + if getregtype(r)=R_ADDRESSREGISTER then + include(addrregset,getsupreg(r)) + else if getregtype(r)=R_INTREGISTER then + include(dataregset,getsupreg(r)) + else + Message(asmr_e_invalid_reg_list_in_movem); + Consume(AS_REGISTER); + end; AS_SLASH: Consume(AS_SLASH); AS_SEPARATOR,AS_COMMA: break; else @@ -1502,14 +1510,15 @@ const end; { end case } end; { end while } oper.opr.typ:= OPR_regset; - oper.opr.regset := regset; + oper.opr.regsetdata := dataregset; + oper.opr.regsetaddr := addrregset; end else { error recovery ... } begin - Message(asmr_e_invalid_reg_list_in_movem); - while not (actasmtoken in [AS_SEPARATOR,AS_COMMA]) do - Consume(actasmtoken); + Message(asmr_e_invalid_reg_list_in_movem); + while not (actasmtoken in [AS_SEPARATOR,AS_COMMA]) do + Consume(actasmtoken); end; end else @@ -1519,34 +1528,47 @@ const Consume(AS_MINUS); reg_one:=actasmregister; if actasmtoken <> AS_REGISTER then - begin - Message(asmr_e_invalid_reg_list_in_movem); - while not (actasmtoken in [AS_SEPARATOR,AS_COMMA]) do - Consume(actasmtoken); - end + begin + Message(asmr_e_invalid_reg_list_in_movem); + while not (actasmtoken in [AS_SEPARATOR,AS_COMMA]) do + Consume(actasmtoken); + end else - begin - { determine the register range ... } - reg_two:=actasmregister; - if getregtype(reg_two)<>R_INTREGISTER then - internalerror(200302191); - if getsupreg(reg_one) > getsupreg(reg_two) then - for i:=getsupreg(reg_two) to getsupreg(reg_one) do - include(regset,i) - else - for i:=getsupreg(reg_one) to getsupreg(reg_two) do - include(regset,i); - Consume(AS_REGISTER); - if not (actasmtoken in [AS_SEPARATOR,AS_COMMA]) then - begin - Message(asmr_e_invalid_reg_list_in_movem); - while not (actasmtoken in [AS_SEPARATOR,AS_COMMA]) do - Consume(actasmtoken); - end; - { set up instruction } - oper.opr.typ:= OPR_regset; - oper.opr.regset := regset; - end; + begin + { determine the register range ... } + reg_two:=actasmregister; + if getregtype(r)=R_ADDRESSREGISTER then + begin + if getsupreg(reg_one) > getsupreg(reg_two) then + for i:=getsupreg(reg_two) to getsupreg(reg_one) do + include(addrregset,i) + else + for i:=getsupreg(reg_one) to getsupreg(reg_two) do + include(addrregset,i); + end + else if getregtype(r)=R_INTREGISTER then + begin + if getsupreg(reg_one) > getsupreg(reg_two) then + for i:=getsupreg(reg_two) to getsupreg(reg_one) do + include(dataregset,i) + else + for i:=getsupreg(reg_one) to getsupreg(reg_two) do + include(dataregset,i); + end + else + Message(asmr_e_invalid_reg_list_in_movem); + Consume(AS_REGISTER); + if not (actasmtoken in [AS_SEPARATOR,AS_COMMA]) then + begin + Message(asmr_e_invalid_reg_list_in_movem); + while not (actasmtoken in [AS_SEPARATOR,AS_COMMA]) do + Consume(actasmtoken); + end; + { set up instruction } + oper.opr.typ:= OPR_regset; + oper.opr.regsetdata := dataregset; + oper.opr.regsetaddr := addrregset; + end; end else { DIVSL/DIVS/MULS/MULU with long for MC68020 only } diff --git a/compiler/rautils.pas b/compiler/rautils.pas index 90e3522554..97ed1d5b64 100644 --- a/compiler/rautils.pas +++ b/compiler/rautils.pas @@ -72,7 +72,7 @@ Function SearchLabel(const s: string; var hl: tasmlabel;emit:boolean): boolean; type TOprType=(OPR_NONE,OPR_CONSTANT,OPR_SYMBOL,OPR_LOCAL, - OPR_REFERENCE,OPR_REGISTER,OPR_REGLIST,OPR_COND,OPR_REGSET,OPR_SHIFTEROP,OPR_MODEFLAGS,OPR_SPECIALREG); + OPR_REFERENCE,OPR_REGISTER,OPR_COND,OPR_REGSET,OPR_SHIFTEROP,OPR_MODEFLAGS,OPR_SPECIALREG); TOprRec = record case typ:TOprType of @@ -83,7 +83,7 @@ type OPR_LOCAL : (localvarsize, localconstoffset: asizeint;localsym:tabstractnormalvarsym;localsymofs:aint;localindexreg:tregister;localscale:byte;localgetoffset,localforceref:boolean); OPR_REGISTER : (reg:tregister); {$ifdef m68k} - OPR_REGLIST : (regset : tcpuregisterset); + OPR_REGSET : (regsetdata,regsetaddr : tcpuregisterset); {$endif m68k} {$ifdef powerpc} OPR_COND : (cond : tasmcond); @@ -1115,6 +1115,10 @@ end; localscale,localgetoffset,localforceref); OPR_REFERENCE: ai.loadref(i-1,ref); +{$ifdef m68k} + OPR_REGSET: + ai.loadregset(i-1,regsetdata,regsetaddr); +{$endif} {$ifdef ARM} OPR_REGSET: ai.loadregset(i-1,regtype,subreg,regset,usermode);