>> >> I managed to remove the errors with the following patch, such that >> everything compiled, but I haven't been able to test it: >> http://j-software.dk/fpc-mipsel.patch
>All fixes of the patch are committed, I solved some things differently though. I am struggling with cpupara.pas. The use of framepoint register ($30) is not right. Printing of floating point number will fail(segmentation fault or deadloop), e.g. writeln(0.3). After some tracing, I've found that it dies in fpc_shortstr_copy, the code is somewhat like this: caller: addiu $2,$29,88 sw $2,($29) lui $4,%hi(U_$P$PROGRAM_$$_S) addiu $4,$4,%lo(U_$P$PROGRAM_$$_S) addiu $6,$0,2 addiu $5,$0,1 addiu $29,$29,-4 jal my_fpc_shortstr_copy nop addiu $29,$29,4 callee: addiu $29,$29,-104 sw $31,44($29) addiu $2,$30,8 addiu $3,$29,96 lw $2,($2) //this is wrong sw $2,($3) $30 is not initialized properly, the use of $30 register will fail. When looking at the code, cgcpu.pas g_proc_entry (here we probably should initialize $30 like powerpc code, if needs_framepoint_ ...) cpupara.pas I don't fully understand the code yet. The generated code with $30 is not from g_proc_entry, instead they are inserted later. Could you help show me the logic: 1, where is the frame pointer code generated and inserted? 2, when will it start to use frame pointer? I have tried that, if the function return a string, $30 will be used; if return an integer, not used. Is it depending on the return type? 3, how is the return value related to parameter handling? It seems that return value is handled as a special parameter? And the whole code seems totally incompatible with standard mips abi, it use 6 registers to pass parameters, while o32 has 4. BTW: I have fixed the boolean64 support use the following patch: --- ncpucnv.pas (版本 21420) +++ ncpucnv.pas (工作副本) @@ -214,6 +214,8 @@ hreg1, hreg2: tregister; opsize: tcgsize; hlabel, oldtruelabel, oldfalselabel: tasmlabel; + newsize : tcgsize; + href: treference; begin oldtruelabel := current_procinfo.CurrTrueLabel; oldfalselabel := current_procinfo.CurrFalseLabel; @@ -223,17 +225,24 @@ if codegenerror then exit; - { byte(boolean) or word(wordbool) or longint(longbool) must } - { be accepted for var parameters } - if (nf_explicit in flags) and - (left.resultdef.size = resultdef.size) and - (left.location.loc in [LOC_REFERENCE, LOC_CREFERENCE, LOC_CREGISTER]) then - begin - location_copy(location, left.location); - current_procinfo.CurrTrueLabel := oldtruelabel; - current_procinfo.CurrFalseLabel := oldfalselabel; - exit; - end; + { Explicit typecasts from any ordinal type to a boolean type } + { must not change the ordinal value } + if (nf_explicit in flags) and + not(left.location.loc in [LOC_FLAGS,LOC_JUMP]) then + begin + location_copy(location,left.location); + newsize:=def_cgsize(resultdef); + { change of size? change sign only if location is LOC_(C)REGISTER? Then we have to sign/zero-extend } + if (tcgsize2size[newsize]<>tcgsize2size[left.location.size]) or + ((newsize<>left.location.size) and (location.loc in [LOC_REGISTER,LOC_CREGISTER])) then + hlcg.location_force_reg(current_asmdata.CurrAsmList,location,left.resultdef,resultdef,true) + else + location.size:=newsize; + current_procinfo.CurrTrueLabel:=oldTrueLabel; + current_procinfo.CurrFalseLabel:=oldFalseLabel; + exit; + end; + location_reset(location, LOC_REGISTER, def_cgsize(resultdef)); opsize := def_cgsize(left.resultdef); case left.location.loc of @@ -242,21 +251,35 @@ if left.location.loc in [LOC_CREFERENCE, LOC_REFERENCE] then begin hreg2 := cg.getintregister(current_asmdata.CurrAsmList, opsize); - cg.a_load_ref_reg(current_asmdata.CurrAsmList, opsize, opsize, left.location.reference, hreg2); +{$ifndef cpu64bitalu} + if left.location.size in [OS_64,OS_S64] then + begin + cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_INT,OS_INT,left.location.reference,hreg2); + hreg1:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT); + href:=left.location.reference; + inc(href.offset,4); + cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_INT,OS_INT,href,hreg1); + cg.a_op_reg_reg_reg(current_asmdata.CurrAsmList,OP_OR,OS_32,hreg1,hreg2,hreg2); + end + else +{$endif not cpu64bitalu} + cg.a_load_ref_reg(current_asmdata.CurrAsmList, opsize, opsize, left.location.reference, hreg2); end else - hreg2 := left.location.Register; -{$ifndef cpu64bit} - if left.location.size in [OS_64, OS_S64] then - begin - hreg1 := cg.getintregister(current_asmdata.CurrAsmList, OS_32); - cg.a_op_reg_reg_reg(current_asmdata.CurrAsmList, OP_OR, OS_32, hreg2, tregister(succ(longint(hreg2))), hreg1); - hreg2 := hreg1; - opsize := OS_32; - end; -{$endif cpu64bit} - hreg1 := cg.getintregister(current_asmdata.CurrAsmList, opsize); - current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SNE, hreg1, hreg2, NR_R0)); + begin + hreg2:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT); +{$ifndef cpu64bitalu} + if left.location.size in [OS_64,OS_S64] then + begin + hreg2:=cg.getintregister(current_asmdata.CurrAsmList,OS_32); + cg.a_op_reg_reg_reg(current_asmdata.CurrAsmList,OP_OR,OS_32,left.location.register64.reghi,left.location.register64.reglo,hreg2); + end + else +{$endif not cpu64bitalu} + cg.a_load_reg_reg(current_asmdata.CurrAsmList,opsize,opsize,left.location.register,hreg2); + end; + hreg1 := cg.getintregister(current_asmdata.CurrAsmList, opsize); + current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SNE, hreg1, hreg2, NR_R0)); end; LOC_JUMP: begin @@ -272,10 +295,26 @@ else internalerror(10062); end; - location.Register := hreg1; +{$ifndef cpu64bitalu} + if (location.size in [OS_64,OS_S64]) then + begin + location.register64.reglo:=hreg1; + location.register64.reghi:=cg.getintregister(current_asmdata.CurrAsmList,OS_32); + if (is_cbool(resultdef)) then + { reglo is either 0 or -1 -> reghi has to become the same } + cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_32,OS_32,location.register64.reglo,location.register64.reghi) + else + { unsigned } + cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_32,0,location.register64.reghi); + end + else +{$endif not cpu64bitalu} + location.Register := hreg1; +{zfx if location.size in [OS_64, OS_S64] then internalerror(200408241); +} current_procinfo.CurrTrueLabel := oldtruelabel; current_procinfo.CurrFalseLabel := oldfalselabel; Best Regards Fuxin Zhang _______________________________________________ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel