diff --git a/compiler/mips/aasmcpu.pas b/compiler/mips/aasmcpu.pas
index 7092c31ac7..6a6ac39edf 100644
--- a/compiler/mips/aasmcpu.pas
+++ b/compiler/mips/aasmcpu.pas
@@ -469,11 +469,12 @@ procedure fixup_jmps(list: TAsmList);
   var
     p,pdelayslot: tai;
     newcomment: tai_comment;
-    newjmp,newnoop: taicpu;
+    newins,newjmp,newnoop: taicpu;
     labelpositions: TFPList;
     instrpos: ptrint;
     l: tasmlabel;
     inserted_something: boolean;
+    href: treference;
   begin
     // if certainly not enough instructions to cause an overflow, dont bother
     if (list.count <= (high(smallint) div 4)) then
@@ -541,11 +542,36 @@ procedure fixup_jmps(list: TAsmList);
                        (ptruint(abs(ptrint(labelpositions[tasmlabel(taicpu(p).oper[0]^.ref^.symbol).labelnr]-instrpos)) - (low(smallint) div 4)) > ptruint((high(smallint) - low(smallint)) div 4)) then
 {$pop}
                       begin
-                        { This is not PIC safe }
-                        taicpu(p).opcode:=A_J;
-                        newcomment:=tai_comment.create(strpnew('fixup_jmps, A_BA changed into A_J'));
-                        list.insertbefore(newcomment,p);
-                      end;
+                        if (cs_create_pic in current_settings.moduleswitches) then
+                          begin
+                            newcomment:=tai_comment.create(strpnew('fixup_jmps, A_BA changed into PIC sequence'));
+                            list.insertbefore(newcomment,p);
+                            href:=taicpu(p).oper[0]^.ref^;
+                            href.refaddr:=addr_pic;
+                            href.base:=NR_GP;
+                            newins:=taicpu.op_reg_ref(A_LW,NR_PIC_FUNC,href);
+                            newins.fileinfo:=taicpu(p).fileinfo;
+                            list.insertbefore(newins,p);
+                            inc(instrpos,2);
+                            if (href.symbol.bind=AB_LOCAL) then
+                              begin
+                                href.refaddr:=addr_low;
+                                href.base:=NR_NO;
+                                newins:=taicpu.op_reg_reg_ref(A_ADDIU,NR_PIC_FUNC,NR_PIC_FUNC,href);
+                                newins.fileinfo:=taicpu(p).fileinfo;
+                                list.insertbefore(newins,p);
+                                inc(instrpos,2);
+                              end;
+                            taicpu(p).opcode:=A_JR;
+                            taicpu(p).loadreg(0,NR_PIC_FUNC);
+                          end
+                        else
+                          begin
+                            taicpu(p).opcode:=A_J;
+                            newcomment:=tai_comment.create(strpnew('fixup_jmps, A_BA changed into A_J'));
+                            list.insertbefore(newcomment,p);
+                          end;
+                       end;
                   A_BC:
                     if (taicpu(p).ops=3) and (taicpu(p).oper[2]^.typ = top_ref) and
                        assigned(taicpu(p).oper[2]^.ref^.symbol) and
@@ -574,11 +600,39 @@ procedure fixup_jmps(list: TAsmList);
                         // add a new unconditional jump between this jump and the label
                         newcomment:=tai_comment.create(strpnew('fixup_jmps, A_BXX changed into A_BNOTXX label;A_J;label:'));
                         list.insertbefore(newcomment,p);
-                        newjmp := taicpu.op_sym(A_J,taicpu(p).oper[2]^.ref^.symbol);
-                        newjmp.is_jmp := true;
-                        newjmp.fileinfo := taicpu(p).fileinfo;
-                        list.insertafter(newjmp,pdelayslot);
-                        inc(instrpos,2);
+                        if (cs_create_pic in current_settings.moduleswitches) then
+                          begin
+                            reference_reset_symbol(href,taicpu(p).oper[2]^.ref^.symbol,0,sizeof(pint));
+                            href.refaddr:=addr_pic;
+                            href.base:=NR_GP;
+                            newins:=taicpu.op_reg_ref(A_LW,NR_PIC_FUNC,href);
+                            newins.fileinfo:=taicpu(p).fileinfo;
+                            list.insertafter(newins,pdelayslot);
+                            pdelayslot:=newins;
+                            inc(instrpos,2);
+                            if (href.symbol.bind=AB_LOCAL) then
+                              begin
+                                href.base:=NR_NO;
+                                href.refaddr:=addr_low;
+                                newins:=taicpu.op_reg_reg_ref(A_ADDIU,NR_PIC_FUNC,NR_PIC_FUNC,href);
+                                newins.fileinfo:=taicpu(p).fileinfo;
+                                list.insertafter(newins,pdelayslot);
+                                pdelayslot:=newins;
+                                inc(instrpos,2);
+                              end;
+                            newjmp:=taicpu.op_reg(A_JR,NR_PIC_FUNC);
+                            newjmp.fileinfo:=taicpu(p).fileinfo;
+                            list.insertafter(newjmp,pdelayslot);
+                            inc(instrpos,2);
+                          end
+                        else
+                          begin
+                            newjmp := taicpu.op_sym(A_J,taicpu(p).oper[2]^.ref^.symbol);
+                            newjmp.is_jmp := true;
+                            newjmp.fileinfo := taicpu(p).fileinfo;
+                            list.insertafter(newjmp,pdelayslot);
+                            inc(instrpos,2);
+                          end;
                         { Add a delay slot for new A_J instruction }
                         newnoop:=taicpu.op_none(A_NOP);
                         newnoop.fileinfo := taicpu(p).fileinfo;